一、題目描述
給出一個鏈表,每 k 個節點一組進行翻轉,並返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。如果節點總數不是 k 的整數倍,那麼將最後剩餘節點保持原有順序。
示例 :
給定這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明 :
你的算法只能使用常數的額外空間。
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
//鏈表一個重要的思路就是留一個頭節點,後面的變化好了直接接入頭節點就好
//所以可以定義一個哨兵
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
上述是題目中已經給出的類的定義以及實例化操作函數。
二、分析:
1.首先要判斷接下來的鏈表中是否還包含K個數據,如果不包含直接跳出進行輸出,因爲要求這個不用排序。
2.進行翻轉操作是用一個for循環來確定循環次數的,保證每次只進行K次循環。我用的方法比較笨,是從head進行尋找,第一次前進k個,將最後一個做爲頭;第二次是進行k-1次前進,直到結束。
3.整體程序分成上面的2塊,定義變量如下:
guard 用來作爲哨兵保存head;
first用來記錄翻轉的第一個;
aim用來表示操作目標;
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode *guard = new ListNode(0);
guard->next = head;
head = guard;
for(; ; ) {
//part 1;
int res_num = 0;
ListNode* last = head->next; //head -> next 由之前的定義決定
for (int i = 0; i < k; i++) {
if (last == NULL) {
break;
}
res_num += 1;
last = last->next;
}
if(res_num != k) {
break;
}
//part 2;
ListNode* first = head->next;
for (int j = 0; j < k; j++) {
int index = k-j-1;
ListNode* aim = first;
while(index --) {
aim = aim->next;
}
head->next = aim;
head = aim;
}
head->next = last;
}
return guard->next;
}
};