Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative.
复习一下数组的rotate,brute force的方法是,保存最后一个数组元素,然后从倒数第二个元素到第一个元素,每个元素往后移一个位置,这样做k次,复杂度是O(n*k)。有一个优化的方法是前n-k个元素翻转,后k个元素翻转,然后整个数组翻转,复杂度O(2n)。数组的翻转比较复杂,因为移动一个元素就要牵动其它所有元素。 链表的rotate 简单些,做法就是从倒数k个结点前面断开,尾部接到链表头,倒数第k个节点作为新head。
直接的想法是基于求倒数第n个节点的算法,这里n是k+1,即倒数第k个节点前面一个节点。双指针p,q。q先走k+1步然后一起走。如果走不了k+1步。说明k>n,取一下模。
有一种更针对本题的做法,只需要一个指针。
1)指针p定位到链表结尾,并计算链表长度n。
2)把尾部连到表头,并计算都到倒数第k个结点前面结点需要的步数m=n-k%/n。
3)p 走m步。head=p->next。 p->next =NULL。
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if (!head || k < 1) return head;
auto q = head;
int len = 1;
for (;q->next;q = q->next) len++;
k = len - k % len;
q->next = head;
for (int i = 0; i < k; i++) q=q->next;
head = q->next;
q->next = NULL;
return head;
}
};