[LeetCode] 61. Rotate List
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, 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实现
/**
* 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实现
/**
* 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;
};
相关题目
61. Rotate List
189. Rotate Array