[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, 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
posted @ 2019-11-05 15:25  CNoodle  阅读(426)  评论(0编辑  收藏  举报