61. Rotate List
Given a linked list, rotate the list to the right by k places, where k is non-negative.
Example 1:
Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL
Example 2:
Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL
题目链接:
https://leetcode.com/problems/rotate-list/
思路
此题比删除倒数第k个元素的题多了一个情况,即需要考虑k大于链表长度时的处理。
k<=链长 时很容易,以下方法针对 k>链长 的情况下寻找更巧妙的解决办法。
法一
算出需要移动的长度,用双指针找到位置,切割后前移。
/**
* 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) {
if(k<=0 || head==NULL || head->next==NULL) return head;
ListNode *l = head, *r = head;
int i=0;
while(i<k){
if(r->next==NULL){
int len = i+1;
k = k % len;
r = head;
i = 0;
}
else{
r = r->next;
++i;
}
}
if (r!=l){
while(r->next!=NULL){
l = l->next;
r = r->next;
}
r->next = head;
head = l->next;
l->next = NULL;
}
return head;
}
};
法二
找到需要移动的长度和所得新链尾元素的关系,首尾相连,找到新尾元素后切割得到所求。
/**
* 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) {
if(k<=0 || head==NULL || head->next==NULL) return head;
ListNode *r = head;
int len=1;
while(r->next!=NULL){
r = r->next;
++len;
}
k = len - k%len - 1;
r->next = head;
r = head;
for(int i=0;i<k;++i){
r = r->next;
}
head = r->next;
r->next = NULL;
return head;
}
};
法一对k<len多的情况更友好,法二省去了移动前的寻找。