算法(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)

相关推荐
AI软著研究员7 小时前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish7 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱8 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
时光不负努力10 小时前
编程常用模式集合
前端·javascript·typescript
时光不负努力10 小时前
ts+vue3开发规范
vue.js·typescript
时光不负努力11 小时前
typescript常用的dom 元素类型
前端·typescript
时光不负努力11 小时前
TS 常用工具类型
前端·javascript·typescript
地平线开发者1 天前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮1 天前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者1 天前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶