算法(TS): 反转链表

反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例一

输入:head = [1,2,3,4,5]

输出:[5,4,3,2,1]

示例二

输入:head = [1,2]

输出:[2,1]

示例三

输入:head = []

输出:[]

提示:

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

进阶: 链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

解法一

  1. 得到链表中节点的总数,total,这里使用 while 语句
  2. 将从头遍历链表,将第n个节点与第total-n个节点的val交换,为了得到total-n个节点需要遍历链表

这种做法并没有反转 Node 实例,只是将它们的值反转了

ts 复制代码
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

function getNode(head: ListNode,NO: number) {
    let n = 1

    while(head && n < NO) {
        head = head.next
        n++
    }

    return head
}

function reverseList(head: ListNode | null): ListNode | null {
    let total = 0
    let p = head
    while(p) {
        p = p.next
        total ++
    }
    p = head
    let n = 0
    let middle = Math.floor(total / 2)
    while(p && n < middle) {
        const other = getNode(head,total-n)
        const temp = p.val
        p.val = other.val
        other.val = temp
        p = p.next
        n++
    }
    return head
};

时间复杂度O(n * n),空间复杂度O(1)

解法二

解法一在查找 total-n 位置上的节点存在重复计算,解法二有一个 Map 保存节点的位置,必须重复计算。

这种做法并没有反转 Node 实例,只是将它们的值反转了

ts 复制代码
function reverseList(head: ListNode | null): ListNode | null {
    let total = 0
    let p = head
    const nodeMap = new Map<number, ListNode>()
    while(p) {
        total ++
        nodeMap.set(total,p)
        p = p.next
    }
    p = head
    let n = 0
    let middle = Math.floor(total / 2)
    while(p && n < middle) {
        const other = nodeMap.get(total-n)
        const temp = p.val
        p.val = other.val
        other.val = temp
        p = p.next
        n++
    }
    return head
};

时间复杂度O(n),空间复杂度O(n)

解法三

创建两个指针 result 和 prev,result 是最新的结果链表,prev 是上一次得到的结果链表,它们的初始值都为 null,遍历 head,result 和 prev 的关系是 result.next = prev,

vbscript 复制代码
/**ts
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

function reverseList(head: ListNode | null): ListNode | null {
    let result = null
    let prev = null
    while(head) {
        prev = result
        result = head
        head = head.next
        result.next = prev
    }
    return result
};

时间复杂度O(n),空间复杂度O(1)

相关推荐
遇见你...1 天前
TypeScript
前端·javascript·typescript
leobertlan1 天前
好玩系列:用20元实现快乐保存器
android·人工智能·算法
青梅橘子皮1 天前
C语言---指针的应用以及一些面试题
c语言·开发语言·算法
_深海凉_1 天前
LeetCode热题100-有效的括号
linux·算法·leetcode
被开发耽误的大厨1 天前
1、==、equals、hashCode底层原理?重写场景?
算法·哈希算法
WolfGang0073211 天前
代码随想录算法训练营 Day38 | 动态规划 part11
算法·动态规划
算是难了1 天前
Nestjs学习总结_3
前端·typescript·node.js
松☆1 天前
C++ 算法竞赛题解:P13569 [CCPC 2024 重庆站] osu!mania —— 浮点数精度陷阱与 `eps` 的深度解析
开发语言·c++·算法
jr-create(•̀⌄•́)1 天前
正则化和优化算法区别
pytorch·深度学习·神经网络·算法
EaseUI1 天前
【Ease UI】2026-04-16 组件更新:新增组件 xly-flow-designer 流程设计器 基于warm-flow二次开发
typescript·前端框架·流程设计器·组件库·warmflow