题目:
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
核心思路:
本题的关键点有两部分,一部分是指定位置反转,另一部分是三段链表的衔接动作。
剖析一下整体思路:
-
需要一个索引标识idx,作为遍历的控制位,对整个链表拆分三个区间:
[1, left), [left, right],(right, 最后] -
需要一个新链表头
newHeader -
需要一个新链表当前节点指针
curHeader
此时,就可以进入链表1段的遍历了。
- 需要一个反转链表头
revHeader - 需要一个反转辅助指针p
此时,遍历并对链表段2中国呢所有[left, right]之间的节点进行反转,拼接。
注意,为了进行后三段链表的拼接,我们要提前做好一些处理:
1)链表段2与链表段3的拼接
当idx===left时,做好指针记录,指针q指向当前节点,也就是指向反转后2段链表的最后一个节点。
2)链表段1与链表段2的拼接
当idx===right时,将curHeader.next(原来curHeader还在指向链表1段的最后一个节点)指向revHeader
让curHeader指向q,指向反转后链表2段的最后一个节点,继续拼接链表3段
解:
var reverseBetween = function (head, left, right) {
let idx = 1; // 控制位,控制左右界限
const newHeader = {}; // 新的链表头
let curHeader = newHeader; // 当前位头指针
let revHeader = null; // 链表反转部分头指针
let p = null; // 链表反转辅助位
let q = null; // 反转链表最后一个节点,用于衔接最后一段链接。
while (head) {
if (idx < left) {
curHeader.next = head;
curHeader = curHeader.next;
head = head.next;
} else if (left <= idx && right >= idx) {
p = head;
head = head.next;
p.next = revHeader;
revHeader = p;
if (left === idx) {
q = p; // 反转链表的最后一个节点,用于衔接最后一个链表3,做好指针记录
}
if (right === idx) {
curHeader.next = revHeader; // 链表2反转完毕,链表1衔接链表2
curHeader = q; // 将当前位指针指向链表2的最后一个节点
}
} else {
curHeader.next = head; // step3: 接着进入最后一段链表
curHeader = curHeader.next;
head = head.next;
}
idx++;
}
return newHeader.next
};
———— 前端、Javascript实现、算法、刷题、leetcode