[路飞]_leetcode 92. 反转链表 II JavaScript版

429 阅读2分钟

「这是我参与11月更文挑战的第 4 天,活动详情查看:2021最后一次更文挑战

题目来源:LeetCode-92. 反转链表II

题目

给你单链表的头指针 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

进阶:你可以使用一趟扫描完成反转吗?

题解

提出问题

  • 如何部分反转且在反转过程中,如何保留链表节点的下一个节点不丢失?

分析 迭代

  • 从示例1来看待反转的链表,想要将left个节点到right个节点的链表进行反转,也就2-4这部分进行反转。

  • 首先定义个temp虚拟节点,将temp.next指向头节点

  • pre指向 temp

  • cur指向cur所指向节点的下一个节点也就是说指向头节点

image.png

  • curpre指针同时往后移动,直到left个节点

image.png

  • 定义contailcon指向pre所指向的节点,tail指向cur所指向的节点。
  • con所指向的节点,将是我们要反转部分的头节点。
  • tail则是反转部分的尾节点。

image.png

  • 此进入反转链表环节,首先定义next指针指向cur所指向节点的下一个节点。

image.png

  • 然后将cur节点指向per节点,将pre指针移动到cur指针所在位置,将cur移动到next指针所在位置,直到per指针指向right个节点。 image.png
  • 重复执行上述操作,当per指针指向right的时候说明,整个需要反转部分的链表的反转执行完毕。

image.png

  • con指针所指向的节点指向现在的pre指针所指向的节点。
  • tail指针所指向的节点指向现在的cur指针所指向的节点。

image.png

  • 整理一下

image.png

代码实现

/**
 * @param {ListNode} head
 * @param {number} left
 * @param {number} right
 * @return {ListNode}
 */
var reverseBetween = function(head, left, right) {
   if(!head) return null
   let temp = new ListNode(-1,head)
   pre = temp
   cnt = right-left+1
   while(--left){
       pre = pre.next
   }
   pre.next = reverse(pre.next,cnt)
   return ret.next
};

var reverse = function(head,n){
    let pre = null
    let cur = head
    while(n--){
        [cur.next,pre,cur]=[pre,cur,cur.next];
    }
    head.next = cur
    return pre
}