61. Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL
and k = 2
,
return 4->5->1->2->3->NULL
.
回想rotate Array的做法,有一种算法如下:
一个数组移动k次后,数组后面的k个元素将反转到数组的首部,下面的算法是:先将数组整体进行反转,然后再将数组的前k个元素进行反转,再将数组的后面n-k个元素进行反转,也就得到了最后的结果。
例子:Let n=7 and k=3.
Original List : 1 2 3 4 5 6 7 After reversing all numbers : 7 6 5 4 3 2 1 After reversing first k numbers : 5 6 7 4 3 2 1 After revering last n-k numbers : 5 6 7 1 2 3 4 --> Result
根据这个思想,我们也可以通过reverse实现链表rotate.
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { ListNode* reverse(ListNode * head)//将一个链表反转 { if(!head||!head->next) return head; ListNode* p=reverse(head->next); head->next->next=head; head->next=NULL; return p; } int len(ListNode* h)//求出链表长度 { int c=0; while(h) { c++; h=h->next; } return c; } ListNode* joint(ListNode* h1,ListNode* h2)//将两个链表合成一个 { if(!h1) return h2; if(!h2) return h1; ListNode* h=h1; while(h1->next) { h1=h1->next; } h1->next=h2; return h; } public: ListNode* rotateRight(ListNode* head, int k) { if(!head||!head->next) return head; int n=len(head); k=k%len(head); if(k==0) return head; ListNode* h=reverse(head);//先整体反转 ListNode* p=h; ListNode*pre=NULL; while(k--) { pre=p; p=p->next; } pre->next=NULL;//将链表分成两部分,前一链表有k个元素,h指向头指针,第二个链表p指向头指针 ListNode* h1=reverse(h);//反转第一个链表 ListNode* h2=reverse(p);//反转第二个链表 ListNode* r=joint(h1,h2);//两者合并 return r; } };