2013.12.21 02:02
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
.
Solution1:
My first solution is clumsy with O(n^2) time complexity (X_X), at least it proves that writing this blog is necessary. Because I wouldn't remember having written such poor codes, and force myself with a better solution, a solution that is decent enough to show you here. See Solution 2, please.
Time complexity is O(n^2), space complexity is O(1).
Accepted code:
1 // 2TLE, 1WA, 1AC 2 /** 3 * Definition for singly-linked list. 4 * struct ListNode { 5 * int val; 6 * ListNode *next; 7 * ListNode(int x) : val(x), next(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 ListNode *rotateRight(ListNode *head, int k) { 13 // IMPORTANT: Please reset any member data you declared, as 14 // the same Solution instance will be reused for each test case. 15 if(head == nullptr){ 16 return head; 17 } 18 19 int i, len; 20 ListNode *tail; 21 ListNode *newhead; 22 ListNode *ptr1, *ptr2; 23 24 len = 0; 25 ptr1 = head; 26 while(ptr1 != nullptr){ 27 ptr1 = ptr1->next; 28 ++len; 29 } 30 k = k % len; 31 if(k == 0){ 32 return head; 33 } 34 35 tail = head; 36 while(tail->next != nullptr){ 37 tail = tail->next; 38 } 39 // Make it a loop~ 40 tail->next = head; 41 42 ptr1 = head; 43 while(true){ 44 ptr2 = ptr1; 45 for(i = 0; i <= k; ++i){ 46 ptr2 = ptr2->next; 47 } 48 if(ptr2 == head){ 49 // 1WA here, should be $ptr1, wrote $ptr2 50 newhead = ptr1->next; 51 ptr1->next = nullptr; 52 break; 53 }else{ 54 // 2TLE here, forgot to move $ptr1 forward 55 ptr1 = ptr1->next; 56 } 57 } 58 59 return newhead; 60 } 61 };
Solution2:
To rotate the list right by k nodes, we'll need to know the location of 4 nodes: head, tail, the last kth, the last (k + 1)th.
The position of the nodes can be determined in O(n) time, after that we'll use O(1) time to alter the $next pointers to new direction.
Time complexity is O(n), space complexity is O(1).
Accepted code:
1 // 1AC, excellent 2 /** 3 * Definition for singly-linked list. 4 * struct ListNode { 5 * int val; 6 * ListNode *next; 7 * ListNode(int x) : val(x), next(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 ListNode *rotateRight(ListNode *head, int k) { 13 if(nullptr == head){ 14 return head; 15 } 16 17 int len = 0; 18 ListNode *p1 = nullptr, *p2 = nullptr, *tail = nullptr; 19 20 // calculate the length of the list 21 p1 = head; 22 len = 0; 23 while(p1 != nullptr){ 24 if(p1->next == nullptr){ 25 tail = p1; 26 } 27 ++len; 28 p1 = p1->next; 29 } 30 if(tail == nullptr){ 31 // cannot possibly happen 32 return nullptr; 33 } 34 35 // reduce k to k % len 36 k = k % len; 37 if(k == 0){ 38 return head; 39 } 40 41 // find the (k + 1)th node from the end 42 p1 = p2 = head; 43 for(int i = 0; i < k + 1; ++i){ 44 p1 = p1->next; 45 } 46 while(p1 != nullptr && p2 != nullptr){ 47 p1 = p1->next; 48 p2 = p2->next; 49 } 50 51 p1 = head; 52 head = p2->next; 53 p2->next = nullptr; 54 tail->next = p1; 55 return head; 56 } 57 };