「这是我参与12月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
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 <= 500
1 <= left <= right <= n
进阶: 你可以使用一趟扫描完成反转吗?
遍历+改变指针
思路
反转部分链表我们这里就需要把需要反转的部分单独领出来,然后对它进行反转
- 为了省去过多边界处理,我们生成一个新节点preHead衔接在链表头部
- 声明一个指针newHead用来遍历链表
- 声明一个index用来记录当前到达第几个节点
- 在遍历过程中找到需要反转的部分,进行反转后,再重新衔接起整个链表
声明四个节点需要
pLeft:原链表中子链表的前一个节点
pRight: 原链表中子链表的后一个节点
childLeft: 子链表的头结点
childRight:子链表的尾结点
- 将子链表分割出来进行反转
- 按照pLeft->childRight---childLeft->pRight的顺序进行重新连接
最后返回preHead.next
var reverseBetween = function (head, left, right) {
var preHead = new ListNode('head')
preHead.next = head
var newHead = preHead
var index = 0
var pLeft, pRight, childLeft, childRight
while (newHead) {
if (index === left - 1) {
pLeft = newHead
childLeft = newHead.next
}
if (index === right) {
childRight = newHead
pRight = newHead.next
}
newHead = newHead.next
index++
}
pLeft.next = null
childRight.next = null
reverseList(childLeft)
pLeft.next = childRight
childLeft.next = pRight
return preHead.next
};
var reverseList = function (head) {
var pre = null
var newHead = head
while (newHead) {
var next = newHead.next
newHead.next = pre
pre = newHead
newHead = next
}
};
复制代码
一次遍历
思路
一次遍历就是在遍历到需要反转的节点时进行逐一处理,例如
1->2->3->4->5 2 4
移动3到1后
1->3->2->4->5
移动4到1后
1->4->3->2->5
- 为了省去过多边界处理,我们生成一个新节点preHead衔接在链表头部
- 在遍历过程中我们要逐一处理需要反转的部分,需要生命以下几个变量
声明四个节点需要
pLeft:原链表中 子链表的前一个节点
preCurr: 当前节点的前一个节点,在子链表中其实一直都是未反转前的第一个节点,即原链表中left的位置,因为这个节点会被反转,一直指向下一个节点,所以在子链表范围,每个当前节点的前一个节点都是他
childLeft: 子链表的第一个节点,即pLeft的下一个节点,实时更新
- 处理流程如下
pLeft ->curr->childLeft->next(剩余节点)
最后返回preHead.next
var reverseBetween = function(head, left, right) {
var preHead = new ListNode('head')
preHead.next = head
var index=0
var newHead = preHead
var pLeft,preCurr
while(newHead){
var next=newHead.next
var curr=newHead
if(index===left-1){
pLeft=newHead
preCurr = childLeft=newHead.next
}
if(index>left&&index<=right){
pLeft.next=curr
curr.next=childLeft
preCurr.next=next
childLeft=curr
}
newHead=next
index++
}
return preHead.next
};
};
复制代码