我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战
206. 反转链表
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
解题思路:
普通解法
-
我们首先需要一个变量
cur
代表指向头节点,pre
暂时为null
不赋值, 第一个循环我们先将cur.next
指向pre
如下图中第一个链表所示。 这样的操作,断掉了之前的cur.next指向,并赋上了一个pre
。 -
我们将
pre
cur
next
往后移动重复以上操作。 -
最终结果就是如下图最后一个链表所示,
pre
到达了原始链表最末。则返回pre
即可。
在链表的解题思路中一定要注意某个节点
next
指向是否断了。否则最终返回结果会造成链表里有环。
var reverseList = function (head) {
let cur= head,pre=null;
while(cur){
let next = cur.next
cur.next = pre //断掉当前指向并指向新的pre
pre = cur
cur = next // 向后移动继续遍历
}
}
递归解法
var reverseList = function(head){
if(!head ||!head.next) return head //递归终止条件
var newhead = reverseList(head.next)
head.next.next = head // head.next看成一个整体然后它的next指向head
head.next = null
return newhead
}
92. 反转链表 II
给你单链表的头指针 head
和两个整数 left
和 right
,其中 left <= right
。请你反转从位置 left
到位置 right
的链表节点,返回 反转后的链表 。
解题思路:
如上图:首先声明一个虚拟头节点dummy
指向head
, 通过left的值 将pre
指针移动到需要翻转链表的头节点的上一个节点,然后声明两个变量cur``next
分别为翻转列表的当前指针和下个指针,循环的次数是right-left
次。
我们需要将cur.next
用next
保存,第一步将pre.next
指向cur.next
cur.next
指向next.next
next.next
指向pre.next
这样就完成了翻转链表的前两个节点的翻转。我们还需要继续,cur
往后移动,继续上一部操作。
直到循环次数遍历完毕。则链表翻转完成。
var reverseBetween = function(head, left, right) {
// 需要一个虚拟头节点
const dummy = {next:head}
let pre = dummy
// 移动pre到翻转链表的头节点上一个节点
for(let i = 0; i<left-1; i++) {
pre = pre.next
}
let cur = pre.next,next
// 翻转逻辑
for(let i =0; i<right-left; i++){
let next = cur.next;
cur.next = next.next;
next.next = pre.next
pre.next = next;
}
return dummy.next
}
结束语
如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~