[路飞]_反转链表II

366 阅读3分钟

题目介绍

给你单链表的头指针 head 和两个整数 leftright ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表

示例1

image.png

输入: 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

leetcode-92 反转链表II b站视频

解题思路

思路一

先将要反转的链表部分从原链表截取出来,将其反转之后再插入到原链表中

1.创建一个虚拟头节点,虚拟头节点的下一节点指向头节点
2.创建 precur 指针分别指向虚拟头节点和头节点
3.precur 依次遍历,直到 pre 处于待反转链表头节点的上一个节点,cur 处于待反转链表的头节点
4.cur 继续遍历,直到待反转链表的尾节点,创建 next 指针指向 cur 节点的下一个节点,并将 cur 的下一节点指向 null
5.反转以 pre.next 为头节点的链表,方法可见[路飞]_反转链表
6.将 pre 节点的下一节点指向反转之后链表的头节点,将反转之后链表的尾节点的下一节点指向 next

1.gif

解题代码

// 反转链表
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.创建 precur 指针分别指向虚拟头节点和头节点
3.precur 依次遍历,直到 pre 处于待反转链表头节点的上一个节点,cur 处于待反转链表的头节点
4.创建 q 指针指向 cur 的下一节点
5.将 cur 的下一节点指向 q 的下一节点
6.将 q 的下一节点指向 pre 的下一节点
7.将 pre 的下一节点指向 q
8.重复 4-7 的过程,直到待反转链表结束

2.gif

解题代码

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
[路飞]_快乐数
[路飞]_反转链表