[LeetCode] 61. Rotate List

Given the head of a linked list, rotate the list to the right by k places.

Example 1:
Example 1
Input: head = [1,2,3,4,5], k = 2
Output: [4,5,1,2,3]

Example 2:
Example 2
Input: head = [0,1,2], k = 4
Output: [2,0,1]

Constraints:
The number of nodes in the list is in the range [0, 500].
-100 <= Node.val <= 100
0 <= k <= 2 * 109

旋转链表。

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

思路

题意很简单,给一个 linked list 和一个数字 k,请你对 linked list 向右 rotate k 次,输出 rotate 后的结果。因为是单链表所以没法从右往左遍历链表。思路是将 input 先连成一个环,然后在新的 head 节点和其之前一个节点处断开即可。

代码里面注意几个细节。

  1. k 是有可能大于链表长度的,所以需要计算链表的长度 n,并用 n % k 计算出实际需要 rotate 的次数。
  2. 需要遍历链表两次,第一遍遍历是为了计算链表的长度,记为 n,同时记得把最后一个节点再连回 head 节点。
  3. 第二遍遍历链表的时候,cur 指针要停在新的 head 节点之前的那个节点。这个节点怎么计算呢?cur 需要从 1 开始,遍历到 n = k % n 处,然后他的下一个节点才是新的 head 节点。

跑一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1 - 2 - 3 - 4 - 5, k = 2

先移动到链表末端,得到长度 len = 5

1 - 2 - 3 - 4 - 5

|______________|

h

h

将链表末端再连到 head 节点,形成一个环

因为需要往右 rotate 2 次,所以实际上是要将 head 指针往后移动 len - k 次,这样 head 指针会在新的 head 之前的一个节点上(4)。此时新的 head 节点是 head.next

最后将 4 5 之间的连接断开即可

复杂度

时间O(n)
空间O(1)

代码

Java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
// corner case
if (head == null || head.next == null) {
return head;
}

// normal case
// 计算list长度
int n = 1;
ListNode cur = head;
while (cur.next != null) {
n++;
cur = cur.next;
}
cur.next = head;

cur = head;
k %= n;
for (int i = 1; i < n - k % n; i++) {
cur = cur.next;
}
ListNode newHead = cur.next;
cur.next = null;
return newHead;
}
}

JavaScript实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var rotateRight = function (head, k) {
// corner case
if (head == null || head.next == null) {
return head;
}

// normal case
let len = 1;
let cur = head;
while (cur.next !== null) {
cur = cur.next;
len++;
}
cur.next = head;

// loop again
for (let i = 1; i < len - (k % len); i++) {
head = head.next;
}
let res = head.next;
head.next = null;
return res;
};

相关题目

1
2
61. Rotate List
189. Rotate Array

[LeetCode] 61. Rotate List
https://shurui91.github.io/posts/493219566.html
Author
Aaron Liu
Posted on
November 5, 2019
Licensed under