题目介绍
给你单链表的头指针 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 <= 5001 <= left <= right <= n
解题思路
思路一
先将要反转的链表部分从原链表截取出来,将其反转之后再插入到原链表中
1.创建一个虚拟头节点,虚拟头节点的下一节点指向头节点
2.创建 pre 和 cur 指针分别指向虚拟头节点和头节点
3.pre 和 cur 依次遍历,直到 pre 处于待反转链表头节点的上一个节点,cur 处于待反转链表的头节点
4.cur 继续遍历,直到待反转链表的尾节点,创建 next 指针指向 cur 节点的下一个节点,并将 cur 的下一节点指向 null
5.反转以 pre.next 为头节点的链表,方法可见[路飞]_反转链表
6.将 pre 节点的下一节点指向反转之后链表的头节点,将反转之后链表的尾节点的下一节点指向 next
解题代码
// 反转链表
var reverseList = function(head, next) {
let pre = head, cur = head.next
while (head.next) {
head.next = cur.next
cur.next = pre
pre = cur
cur = head.next
}
head.next = next
return pre
}
var reverseBetween = function(head, left, right) {
const newHead = new ListNode(-1, head)
let pre = newHead, cur = head, next
let n = right - left + 1
while(--left) {
// 反转链表的前一个节点
pre = pre.next
// 反转链表开始的节点
cur = cur.next
}
while(--n) {
// 反转链表结束的节点
cur = cur.next
}
// 反转链表的下一个节点
next = cur.next
cur.next = null
const reverseHead = reverseList(pre.next, next)
pre.next = reverseHead
return newHead.next
};
思路二(头插法)
将遍历到的待反转链表的每个节点(头节点除外)插入到反转链表的上一个节点和反转链表的当前头节点之间
1.创建一个虚拟头节点,虚拟头节点的下一节点指向头节点
2.创建 pre 和 cur 指针分别指向虚拟头节点和头节点
3.pre 和 cur 依次遍历,直到 pre 处于待反转链表头节点的上一个节点,cur 处于待反转链表的头节点
4.创建 q 指针指向 cur 的下一节点
5.将 cur 的下一节点指向 q 的下一节点
6.将 q 的下一节点指向 pre 的下一节点
7.将 pre 的下一节点指向 q
8.重复 4-7 的过程,直到待反转链表结束
解题代码
var reverseBetween = function(head, left, right) {
const newNode = new ListNode(-1, head)
let pre = newNode, cur = head
let n = right - left + 1
while (--left) {
pre = pre.next
cur = cur.next
}
while (--n) {
const q = cur.next
cur.next = q.next
q.next = pre.next
pre.next = q
}
return newNode.next
};
以上就是本题的解题思路,可以查看我的其他文章
[路飞]_环形链表
[路飞]_环形链表II
[路飞]_快乐数
[路飞]_反转链表