[路飞]_程序员必刷力扣题: 206. 反转链表

211 阅读2分钟

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

206. 反转链表

给你单链表的头节点 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  

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

递归

思路

递归的时候我们希望可以先将,当前节点的next指向的后续子链表进行反转,反转结束后next从开始的头结点就变成了尾结点,所以我们这里需要用一个变量next来保存一下这个节点,以便往后衔接

处理完毕以后我们可以得到一个,反转后的链表res,我们也保存了他的尾结点next,此时只需要将next指向当前节点head,并且处理当前节点的next指针为null,否则可能会出现环状结构

具体操作如下

在递归的时候我们的步骤

  • 处理边界条件,head以及head.next为空的时候直接返回当前的head节点
  • 只需要处理当前节点与下一个节点的反转
  • 后续链表继续使用递归处理

最后返回递归的结果

var reverseList = function (head) {
    if (!head || !head.next) return head

    var next = head.next
    var res = reverseList(head.next)
    next.next = head
    head.next = null
    return res          
};

遍历

思路

遍历数组的每个节点来反转链表

  • 处理边界条件
  • 提前保存下一个节点next,用来往下遍历链表,改变当前节点next指向
  • 设置pre来保存上一个节点,使当前节点next可以指向上一个节点,及时更新pre

返回条件

当遍历到最后一个节点(next为null)时,处理玩指针next后直接返回当前节点

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