[路飞]_Leetcode 206反转链表

251 阅读2分钟

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

从今天开始在掘金输出自己在leetcode上面的做题记录😁。

题目链接在这里 leetcode 206-反转链表

题意

image.png

由图可以看到,题目给出的是一个单链表,需要返回整个链表经过反转之后的链表。

思路

一种直观的思路是,沿着链表从前往后走,依次将当前节点的next指针指向上个节点。

image.png 比如,对1->2->3->4->5->null进行反转。

  • 首先,定义一个初始变量pre = null,迭代的变量cur = head,默认指向head。
  • 在向后迭代过程中,由于要改变当前节点的next指针指向,为防止next节点被释放,导致迭代中止,这里需要使用变量next=cur.next来保存当前节点的next指针。
  • 然后,将当前节点的next指针指向上一个节点,即 cur.next = pre
  • 再更新pre变量,即pre = cur,
  • 然后更新当前节点为他的下一个节点的位置,即cur = next.
  • 继续下一个节点的反转...

这样,最终就按照1 2 3 4 5 的顺序依次将每个节点的next指针指向上次反转之后pre节点,完成整个链表的反转,反转结果保存在pre中。

另外一种不太直观的思路是,从后往前进行反转操作

由于需要从后向前遍历链表,我们自然而然就想到了递归的思路, image.png

  • 递归从倒数第二节点开始
  • 首先,将当前节点指向null
  • 将下一个节点的next指针指向当前节点,并保存下一个节点的引用
  • 重复上述步骤,就完成了从后往前两两的反转了整个链表

代码实现

// 迭代法
var reverseList = head => {
    if(head == null) return head
    let pre = null,cur = head,next
    while(cur){
        next = cur.next
        cur.next = pre
        pre = cur
        cur = next
    }
    return pre
}
// 递归法
var reverseList = head => {
    if(head == null || head.next == null) return head
    let p = reverseList(head.next),tail = head.next
    tail.next = head
    head.next = null
    return p
}

结束语

经过反转链表这道题的分析,可以看出,其中的操作还是挺抽象的,个人觉得在不熟悉的时候,分析题目时画一张图会起到很大的帮助。

如果有更好的分析思路,欢迎大家在评论区发表看法!⛄