单链表指定区间反转
力扣92题,给定单链表的头指针
head
,和两个整数left
和right
,其中left <= right
.反转从位置left
到right
的链表结点,并返回反转后的链表。
用两种较好的方法来解决这道题,一种是不带虚拟头结点的方法叫做穿针引线法,另外一种是用到虚拟头结点的方法叫做头插法。
1.头插法
反转的整体思想:是在需要反转的区间里,每遍历到一个结点,让这个新节点来到反转部分的起始位置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DejXtV8e-1690549641475)
每走一步都需要考虑结点指针怎么指,既要将结点摘下来接到对应的位置上,还需要保证后续结点能够找到。从左边边界点的前一个结点开始进行反转,每次将当前结点插入到反转链表的起始位置。
var reverseBetween = function(head, left, right) {
// 如果链表只有一个元素,返回头结点即可
if (!head || !head.next) return head;
const dummyHead = new ListNode(-1);
dummyHead.next = head;
let previousNode = dummyHead;
// 从左边边界点的前一个结点开始进行反转
for (let i = 0; i < left - 1; i++) {
previousNode = previousNode.next;
}
let currentNode = previousNode.next;
for (let i = 0; i < right - left; i++) {
const nextNode = currentNode.next;
currentNode.next = nextNode.next;
nextNode.next = previousNode.next;
previousNode.next = nextNode;
}
return dummyHead.next;
}
2.穿针引线法
指定区间反转的穿针引线算法可以复用链表反转算法,反转流程如图所示。
- )得到反转区间链表
- )切断链接,使反转区间链表成为一个独立链表
- )将反转区间链表进行反转重新接回原链表中,最后返回最终链表
// 穿针引线法
var reverseBetween = function(head, left, right) {
if (!head || !head.next) return head;
const dummyHead = new ListNode(-1);
dummyHead.next = head;
let previousNode = dummyHead;
// 第一步,找到反转区间左边界结点的前一个结点
for (var i = left - 1; i > 0; i--) {
previousNode = previousNode.next;
}
// 第二步,找到反转区间右边界结点
let rightEdgeNode = previousNode;
for (var i = right - left + 1; i > 0; i--) {
rightEdgeNode = previousNode.next;
}
// 第三步,得到反转区间链表
let leftEdgeNode = previousNode.next;
let currentNode = rightEdgeNode.next;
// 第四步,切断链接,使反转区间链表成为一个独立链表
previousNode.next = rightEdgeNode.next = null;
// 第五步,将反转区间链表进行反转
reverseLinkedList(leftEdgeNode);
// 第六步,将反转后的链表重新接回原链表中并返回最终链表
previousNode.next = rightEdgeNode;
leftEdgeNode.next = currentNode;
return dummyHead.next;
}
// 迭代法反转链表
const reverseLinkedList(head) {
let previousNode = null;
let currentNode = head;
while (currentNode) {
const nextNode = currentNode.next;
currentNode.next = previousNode;
previousNode = currentNode;
currentNode = nextNode;
}
}
总结
在进行反转的过程中,难点就是想清楚结点指针该怎么变化,搞清楚这点,反转就容易理解了。