[前端]_一起刷leetcode 206. 反转链表

263 阅读2分钟

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

题目

206. 反转链表

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

 

示例 1:

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

示例 2:

输入: head = [1,2]
输出: [2,1]

示例 3:

输入: head = []
输出: []

 

提示:

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

 

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

迭代

思路

  1. 缓存一个空节点prev,然后对链表进行一轮遍历;
  2. 每次循环,把当前节点截取出来,拼接到prev的最前面;
  3. 循环结束,返回当前prev节点

实现

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    let prev = null;
    while (head) {
        const next = head.next;
        head.next = prev;
        prev = head;
        head = next;
    }

    return prev;
};

递归

思路

  1. 当前节点, 如果后续还有节点, 递归, 找到下个节点, 一直找到最后一个节点;
  2. 从最后一个节点开始返回, 下一个节点返回完, 改变下一个节点的next指向自己;
  3. 拆断当前节点原本的指向;
  4. 递归结束,返回最后一个节点即可。

例如: 1 -> 2 -> 3

一层层下钻,递归走到3,返回它作为最后一个节点,也就是我们待会儿的结果。

然后在2这里,改变3的指向。

2的时候 head.next指的是3head.next.next 原本是链表末尾,指向Null, 我们要让他掉头指向当前节点, 代码如下: head.next.next = head;

这是链表会形成闭环,因为 2 指向 33又指向2。需要拆开原链表的指向 head.next = null;

递归结束返回的时候, 每一轮改变节点的指向即可。

实现

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    if (!head || !head.next) {
        return head;
    }

    let newNode = reverseList(head.next);
    // 将下个节点指向转为自己
    head.next.next = head;
    // 拆开正向的指向,否则将形成闭环。我看着你,你看着我
    head.next = null;

    return newNode;
};

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。