「这是我参与11月更文挑战的第 4 天,活动详情查看:2021最后一次更文挑战」
题目来源:LeetCode-92. 反转链表II
题目
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例 1:
输入: head = [1,2,3,4,5], left = 2, right = 4
输出: [1,4,3,2,5]
示例 2:
输入: head = [5], left = 1, right = 1
输出: [5]
提示:
链表中节点数目为
n
1 <= n <= 500-500 <= Node.val <= 5001 <= left <= right <= n
进阶:你可以使用一趟扫描完成反转吗?
题解
提出问题
- 如何部分反转且在反转过程中,如何保留链表节点的下一个节点不丢失?
分析 迭代
-
从示例1来看待反转的链表,想要将
left个节点到right个节点的链表进行反转,也就2-4这部分进行反转。 -
首先定义个
temp虚拟节点,将temp.next指向头节点 -
pre指向temp -
cur指向cur所指向节点的下一个节点也就是说指向头节点
- 将
cur、pre指针同时往后移动,直到left个节点
- 定义
con与tail,con指向pre所指向的节点,tail指向cur所指向的节点。 con所指向的节点,将是我们要反转部分的头节点。tail则是反转部分的尾节点。
- 此进入反转链表环节,首先定义
next指针指向cur所指向节点的下一个节点。
- 然后将
cur节点指向per节点,将pre指针移动到cur指针所在位置,将cur移动到next指针所在位置,直到per指针指向right个节点。 - 重复执行上述操作,当
per指针指向right的时候说明,整个需要反转部分的链表的反转执行完毕。
- 将
con指针所指向的节点指向现在的pre指针所指向的节点。 - 将
tail指针所指向的节点指向现在的cur指针所指向的节点。
- 整理一下
代码实现
/**
* @param {ListNode} head
* @param {number} left
* @param {number} right
* @return {ListNode}
*/
var reverseBetween = function(head, left, right) {
if(!head) return null
let temp = new ListNode(-1,head)
pre = temp
cnt = right-left+1
while(--left){
pre = pre.next
}
pre.next = reverse(pre.next,cnt)
return ret.next
};
var reverse = function(head,n){
let pre = null
let cur = head
while(n--){
[cur.next,pre,cur]=[pre,cur,cur.next];
}
head.next = cur
return pre
}