「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
从今天开始在掘金输出自己在leetcode上面的做题记录😁。
题目链接在这里 leetcode 206-反转链表
题意
由图可以看到,题目给出的是一个单链表,需要返回整个链表经过反转之后的链表。
思路
一种直观的思路是,沿着链表从前往后走,依次将当前节点的next指针指向上个节点。
比如,对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中。
另外一种不太直观的思路是,从后往前进行反转操作
由于需要从后向前遍历链表,我们自然而然就想到了递归的思路,
- 递归从倒数第二节点开始
- 首先,将当前节点指向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
}
结束语
经过反转链表这道题的分析,可以看出,其中的操作还是挺抽象的,个人觉得在不熟悉的时候,分析题目时画一张图会起到很大的帮助。
如果有更好的分析思路,欢迎大家在评论区发表看法!⛄