这是我参与11月更文挑战的第8天,活动详情查看:[2021最后一次更文挑战]
题目
给你单链表的头指针 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]
思路 1、我们定义两个指针,分别称之为 g(guard 守卫) 和 p(point)。 我们首先根据方法的参数 m 确定 g 和 p 的位置。将 g 移动到第一个要反转的节点的前面,将 p 移动到第一个要反转的节点的位置上。我们以 m=2,n=4为例。 2、将 p 后面的元素删除,然后添加到 g 的后面。也即头插法。 3、根据 m 和 n 重复步骤(2) 4、返回 dummyHead.next
代码
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} left
* @param {number} right
* @return {ListNode}
*/
var reverseBetween = function(head, left, right) {
// 定义虚拟头节点处理一个节点的特殊情况
let dummyHead = new ListNode(0, head);
// 定义双指针写法一:
let g = dummyHead,
p = dummyHead.next;
// 移动双指针到 g = left - 1, p = left 的位置
for (let i = 0; i < left - 1; i++) {
g = g.next;
p = p.next;
}
// 头插法处理
for (let i = 0; i < right - left; i++) {
const removedNode = p.next;
p.next = p.next.next;
removedNode.next = g.next;
g.next = removedNode;
}
return dummyHead.next;
};
先把那个反转链表1做一下, 那个题目搞懂了, 这个就很容易懂了 分三步走:
- 遍历到m的前一个位置
superior(因为需要遍历到前一个位置, 所以最好创建一个虚拟头结点) - 定义一个节点使其指向m的位置
cur = superior.next然后就是按照反转链表1的方式直接套就好了. 需要注意一下循环的边界 循环结束之后, 脑海中要浮现出三个指针的位置(浮现个屁, 用纸笔画一下吧骚年)prev 指向n-m的位置,也就是最后一个旋转的节点cur和next都指向n-m的下一个位置 - 最后调整一下
superior.next(m处的节点)和prev(n-m位置处)这两个节点的指向即可