061.旋转链表

题目

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

示例 1: 1 -> 2 -> 3 -> 4 -> 5

rotate 1: 5 -> 1 -> 2 -> 3 -> 4 rotate 2: 4 -> 5 -> 1 -> 2 -> 3

输入:head = [1,2,3,4,5], k = 2 输出:[4,5,1,2,3]

示例 2: 0 -> 1 -> 2

rotate 1: 2 -> 1 -> 0 rotate 2: 1 -> 2 -> 0 rotate 3: 0 -> 1 -> 2 rotate 4: 2 -> 0 -> 1

输入:head = [0,1,2], k = 4 输出:[2,0,1]

提示:

  • 链表中节点的数目在范围 [0, 500] 内
  • -100 <= Node.val <= 100
  • 0 <= k <= 2 * 10^9

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

思路

将链表中每个节点向右移动K个位置,也就是将链表中倒数第K个节点作为头节点,其前面的所有节点放在原链表尾节点之后。

因此整体思路就是找到倒数第K个节点的前一个节点,然后让链表首尾相连,第K个节点作为链表旋转后的新的头节点,其前一个节点作为链表旋转后的尾节点。

作者:hardcore-aryabhata 链接:https://leetcode-cn.com/problems/rotate-list/solution/dong-hua-yan-shi-kuai-man-zhi-zhen-61-xu-7bp0/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

JS实现

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var rotateRight = function (head, k) {
  if (head === null) {
    return head;
  }

  // 获取链表的长度
  const getLength = (head) => {
    let length = 0;
    while (head != null) {
      length++;
      head = head.next;
    }
    return length;
  };

  // 定义快指针
  let fast = head;
  // 定义快指针
  let slow = head;

  // 1 -> 2 -> 3
  // k = 1, 1%3=1, 3 -> 1 -> 2
  // k = 2, 2%3=2, 2 -> 3 -> 1
  // k = 3, 3%3=0, 1 -> 2 -> 3
  // k = 4, 4%3=1, 3 -> 1 -> 2

  const length = getLength(head);
  k = k % length;

  // 快指针先走k步
  for (let i = 0; i < k; i++) {
    fast = fast.next;
  }

  // 快慢指针一起走
  while (fast.next != null) {
    fast = fast.next;
    slow = slow.next;
  }
  // 快指针 指向 头节点,形成环
  fast.next = head;
  // 新的头节点即为慢指针的下个节点
  head = slow.next;
  // 慢指针的下个节点指向null,断开环
  slow.next = null;
  return head;
};