LeetCode刷题挑战-javascript:206.反转链表

109 阅读1分钟

image.png

「一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。」

题目

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

image.png

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

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

示例 2:

image.png

输入:head = [1,2]

输出:[2,1]

示例 3:

输入:head = []

输出:[]  

提示:

  • 链表中节点的数目范围是 [0, 5000]

  • -5000 <= Node.val <= 5000  

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

解题思路

方法一:迭代法

假设链表为 1→2→3→∅,我们想要把它改成 ∅←1←2←3。

在遍历链表时,将当前节点的 \textit{next}next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。

var reverseList = function(head) {
    let prev = null;
    let curr = head;
    while (curr) {
        const next = curr.next;
        curr.next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
};

复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。

  • 空间复杂度:O(1)。

方法二:递归法

递归版本稍微复杂一些,其关键在于反向工作。假设链表的其余部分已经被反转,现在应该如何反转它前面的部分?

假设链表为:

n1 →…→n k−1 →n k →n k+1 →…→n m →∅

若从节点 n k+1 到 n m已经被反转,而我们正处于 n k。

n 1 ​ →…→n k−1 ​ →n k ​ →n k+1 ​ ←…←n m ​

我们希望 n k+1 ​ 的下一个节点指向 n k ​ 。

所以,n k ​ .next.next=n k ​ 。

需要注意的是 n 1 ​ 的下一个节点必须指向 ∅。如果忽略了这一点,链表中可能会产生环。

var reverseList = function(head) {
    if (head == null || head.next == null) {
        return head;
    }
    const newHead = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return newHead;
};

复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的长度。需要对链表的每个节点进行反转操作。

  • 空间复杂度:O(n),其中 n 是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 n 层。

结束语

这里是小葵🌻,只要把心朝着太阳的地方,就会有温暖~

让我们一起来攻克算法难关吧!!

往期精彩回顾

LeetCode刷题挑战-javascript:169.多数元素

LeetCode刷题挑战-javascript:160.相交链表

LeetCode刷题挑战-javascript:155.最小栈

LeetCode刷题挑战-javascript:144.二叉树的前序遍历

LeetCode刷题挑战-javascript:141.环形链表

更多往期精彩内容请前往个人主页查看👉 努力的小葵个人主页