題目描述:
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
Example:
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
Note:
- Only constant extra memory is allowed.
- You may not alter the values in the list's nodes, only nodes itself may be changed.
代碼:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(head == NULL) return NULL;
if(k == 0) return head;
int length = 0;
ListNode* current = head;
ListNode* pre = new ListNode(0);
ListNode* result = pre;
pre -> next = head;
while(current != NULL){
length++;
current = current -> next;
}
current = head;
ListNode* pos = current -> next;
while(length >= k){
for(int i = 0; i < k - 1; i++){
current -> next = pos -> next;
pos -> next = pre -> next;
pre -> next = pos;
pos = current -> next;
}
length -= k;
pre = current;
current = current -> next;
if(current != NULL) pos = current -> next;
}
return result->next;
}
};
本題目是一個hard題,一次AC,但是有參考別人的方法。最開始自己的思路是,寫一個鏈表反轉函數, 每次從原鏈表中截取長度爲k的鏈表,然後調用該函數反轉,然後繼續截取k個,反轉,以此類推。但是後來仔細審題,發現題目要求空間複雜度必須爲O(1),因此該方法就被放棄了。後來又想着每個結點和他之後的第k-1個結點互換,但是這樣的話,在換的過程中會導致大量的時間複雜度,因此也被放棄。最終參考別人的思路,如下:
首先遍歷一遍鏈表,得到鏈表的長度length,然後,再對鏈表進行遍歷。k個一組進行處理,在每個小組中,分別記錄一下該組的前一結點pre,然後將該組頭結點之後的所有結點依次插入到pre結點後即可,其實就是用頭插的方法,反轉鏈表。最開始自己寫的鏈表反轉函數也是用同樣的方法反轉的,但是在之後考慮的方法中,腦子抽抽了沒想到這麼做記錄一下就可以,難受。
靜心盡力!