LeetCode题解:61. 旋转链表,双指针,JavaScript,详细注释

352 阅读2分钟

原题链接:61. 旋转链表

解题思路:

  1. 输入:head = [1,2,3,4,5], k = 2
  2. 如果将链表连接成环,会变成这样的样子:[1,2,3,4,5,1,2,3,4,5, ...]
  3. 此时我们只要将3 → 4的连接打断,即可得到结果:[4,5,1,2,3]
  4. 可以把问题按步骤解决:
    • 创建两个指针,slow = 1, fast = 1
    • fast向前移动2位,指向3
    • 再将slowfast同时向前移动,知道fast指向尾结点,此时slow正好停留在链表要断点的位置。
    • fasthead连接,让链表形成环。
    • 缓存新链表的头结点const newHead = slow.next,将链表打断slow.next = null
    • 将新链表的头结点newHead返回。
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var rotateRight = function (head, k) {
  // 以下条件无需旋转,直接返回即可
  if (
    // 链表为空
    !head ||
    // 链表只有一个节点
    !head.next ||
    // 旋转数量为0
    k === 0
  ) {
    return head;
  }

  // 使用一个指针,统计链表长度
  let node = head;
  // 统计节点数量,指针初始指向头结点,因此初始值为1
  let length = 1;

  // 不断移动指针,但它停在尾结点时,完成链表长度的统计
  while (node.next) {
    length++;
    node = node.next;
  }

  // 创建快慢指针,初始时都指向头节点
  let slow = head;
  let fast = head;
  // 链表旋转节点数量,k可能大于链表长度,因此需要取余
  k = k % length;

  // 如果k为0,无需旋转,直接返回即可
  if (k === 0) {
    return head;
  }

  // 将快指针向前移动k位,此时快慢指针的距离为k
  while (--k >= 0) {
    fast = fast.next;
  }

  // 将快指针移动到尾结点,此时慢指针停留在需要打断点的节点
  while (fast.next) {
    slow = slow.next;
    fast = fast.next;
  }

  // 将快指针与原链表头结点连接,让链表形成环
  fast.next = head;
  // 新链表的头结点在慢指针的下一个节点,将其缓存
  const newHead = slow.next;
  // 将慢指针与新链表头结点打断
  slow.next = null;

  // 返回新链表
  return newHead;
};