题目介绍
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
- 因为需要反转的部分是left到right的节点,所以要先找到对应的节点,然后把头尾连接切断,然后做这部分的链表反转
- 切断左边的连接,切断左边的连接是要找left所在的节点的前一个节点,在切断连接前需要把left存起来,因为left节点反转后变成了右边的节点,右边节点需要剩下的尾部节点连接起来
- 切断右边的连接钱,需要把尾部节点存起来
- 切断连接后做反转,反转后需要把原来的left的前一个节点的next指向到原来的右边节点,原来的left节点的下一个节点指向尾部节点
function ListNode(val, next) {
this.val = val === undefined ? 0 : val
this.next = next === undefined ? null : next
}
var reverseList = function (head) {
let cur = head
let pre = null
while (cur) {
// 暂存下个节点,这样指针才可以滑动
let nxt = cur.next
// 当前节点的next指向上一个节点,断开了与下个节点的连接
cur.next = pre
// 此次循环结束前 保存当前节点为上一个节点
pre = cur
// 滑到下一个节点
cur = nxt
}
return pre
}
function reverseBetween(head, left, right) {
const dummyNode = new ListNode(-1)
dummyNode.next = head
let pre = dummyNode
// 先找到左边节点的前一个节点
for(let i = 0; i < left - 1; i++) {
pre = pre.next
}
let nodeRight = pre
// 找到右边节点
for (let i = 0; i < right - left + 1; i++) {
nodeRight = nodeRight.next
}
// 保存需要反转部分的头部节点, 反转后就变成右边去了, 它的next需要重新接上尾部的节点
let leftNode = pre.next
// 保存尾部节点,反转后需要把尾部
let endNode = nodeRight.next
// 断开头部的节点的next
pre.next = null
// 断开右边节点的next
nodeRight.next = null
// 反转
reverseList(leftNode)
// 重新连接
leftNode.next = endNode
pre.next = nodeRight
return dummyNode.next
}