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

相关推荐
长安er42 分钟前
LeetCode215/347/295 堆相关理论与题目
java·数据结构·算法·leetcode·
元亓亓亓1 小时前
LeetCode热题100--62. 不同路径--中等
算法·leetcode·职场和发展
小白菜又菜1 小时前
Leetcode 1925. Count Square Sum Triples
算法·leetcode
登山人在路上2 小时前
Nginx三种会话保持算法对比
算法·哈希算法·散列表
写代码的小球2 小时前
C++计算器(学生版)
c++·算法
AI科技星3 小时前
张祥前统一场论宇宙大统一方程的求导验证
服务器·人工智能·科技·线性代数·算法·生活
Fuly10243 小时前
大模型剪枝(Pruning)技术简介
算法·机器学习·剪枝
Xの哲學3 小时前
Linux网卡注册流程深度解析: 从硬件探测到网络栈
linux·服务器·网络·算法·边缘计算
bubiyoushang8883 小时前
二维地质模型的表面重力值和重力异常计算
算法
仙俊红4 小时前
LeetCode322零钱兑换
算法