算法(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 小时前
J6B vio scenario sample
算法
BothSavage13 小时前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn13 小时前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法
烬羽15 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
先吃饱再说1 天前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰1 天前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 天前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六2 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程