Given the head of a linked list, rotate the list to the right by k places.
Example 1:
Input: head = [1,2,3,4,5], k = 2
Output: [4,5,1,2,3]
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 节点和其之前一个节点处断开即可。
代码里面注意几个细节。
- k 是有可能大于链表长度的,所以需要计算链表的长度 n,并用 n % k 计算出实际需要 rotate 的次数。
- 需要遍历链表两次,第一遍遍历是为了计算链表的长度,记为 n,同时记得把最后一个节点再连回 head 节点。
- 第二遍遍历链表的时候,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
|
class Solution { public ListNode rotateRight(ListNode head, int k) { if (head == null || head.next == null) { return head; } 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
|
var rotateRight = function (head, k) { if (head == null || head.next == null) { return head; }
let len = 1; let cur = head; while (cur.next !== null) { cur = cur.next; len++; } cur.next = head;
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
|