92.反转链表2

LeetCode 原题链接 题目

代码实现

方案一

  • 使用一个 dummy 节点来简化边界情况的处理。
  • 使用两个指针 leftNoderightNode 分别找到需要反转的区间的前一个节点和后一个节点。
  • 反转区间内的节点,反转后原来的区间头变成区间尾,原来的区间尾变成区间头。
  • leftNode 的 next 指向反转后的区间头,将反转后的区间尾的 next 指向 rightNode,完成连接。
var reverseBetween = function (head, left, right) {
  if (head === null) return head;

  const dummy = new ListNode(0, head);

  let leftNode = dummy;
  for (let i = 0; i < left - 1; i++) {
    leftNode = leftNode.next;
  }
  let rightNode = dummy;
  for (let j = 0; j < right; j++) {
    rightNode = rightNode.next;
  }

  let prev = rightNode.next;
  let cur = leftNode.next;
  for (let k = 0; k < right - left + 1; k++) {
    let temp = cur.next;
    cur.next = prev;
    prev = cur;
    cur = temp;
  }

  leftNode.next = prev;

  return dummy.next;
};

方案二

  • 只找到 left 前一个节点,然后反转固定次数。不需要提前找 rightNode
var reverseBetween = function (head, left, right) {
  if (head === null) return head;

  const dummy = new ListNode(0, head);

  // 1. 找到 left 前一个节点
  let beforeLeft = dummy;

  for (let i = 1; i < left; i++) {
    beforeLeft = beforeLeft.next;
  }

  // 2. 开始反转 [left, right]
  const leftNode = beforeLeft.next;
  let prev = null;
  let cur = leftNode;

  for (let i = 0; i < right - left + 1; i++) {
    const next = cur.next;
    cur.next = prev;
    prev = cur;
    cur = next;
  }

  // 3. 接回链表
  beforeLeft.next = prev;
  leftNode.next = cur;

  return dummy.next;
};