一.问题描述
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
.
二.我的解题思路
链表相关的问题往往都比较直观明确,可以借助画图等方式来辅助理解。本题是链表中经典的倒数第k个节点问题的变种,问题的关键点自然也就是双指针的策略。采用两个指针,一个指针指向链表头,另一个指针指向从头开始走k步所到达的节点。然后开始遍历链表,每次都将两个指针同时往后移,直至到达链表尾。
本题有一个地方说明不太清,就是k>链表长度len的情况。根据测试案例的情况来看,k采用的递增方式应该是k mod len。所以需要预先遍历一下链表得到链表长度len,然后再得到k mod len。 测试通过的程序如下,复杂度应该是o(n):
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
ListNode * res;
if(head==NULL) return NULL;
ListNode * curr = head;ListNode * k_next = head; ListNode * pre=head;
int cnt=1;
while(k_next->next!=NULL){
k_next = k_next->next;
cnt++;
}
k_next = head;
int len =cnt;
k = k%len;
if(k==0) return head;
cnt=1;
while(k_next->next!=NULL && cnt<k){
k_next = k_next->next;
cnt++;
}
if(cnt<k) return head;
if(k_next->next==NULL) return head;
cnt=1;
while(k_next->next!=NULL){
pre=curr;
curr=curr->next;
k_next=k_next->next;
cnt++;
}
k_next->next = head;
pre->next=NULL;
res = curr;
return res;
}
};