[路飞]_反转链表II

156 阅读2分钟

题目介绍

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

  1. 因为需要反转的部分是left到right的节点,所以要先找到对应的节点,然后把头尾连接切断,然后做这部分的链表反转
  2. 切断左边的连接,切断左边的连接是要找left所在的节点的前一个节点,在切断连接前需要把left存起来,因为left节点反转后变成了右边的节点,右边节点需要剩下的尾部节点连接起来
  3. 切断右边的连接钱,需要把尾部节点存起来
  4. 切断连接后做反转,反转后需要把原来的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
}