LeetCode 25 —— K 個一組翻轉連結串列
阿新 • • 發佈:2018-12-17
1. 題目
2. 解答
- 首先,利用快慢指標確定連結串列的總結點數。
- 偶數個結點時,結點個數等於 i * 2。
-
奇數個結點時,結點個數等於 i * 2 + 1。
-
然後將連結串列的每 K 個結點劃分為一組。迴圈對每組的子連結串列進行翻轉,並依次拼接起來。
-
最後,將多餘的結點拼接在新連結串列最後面即可。
-
程式碼如下
/**
* 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 || head->next == NULL || k == 1) //空連結串列或只有一個結點或者 k=1 不用翻轉,直接返回
{
return head;
}
else
{
int node_num = 0; // 連結串列的結點個數
ListNode* slow = head;
ListNode* fast = head;
// 利用快慢指標確定連結串列的結點總個數
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
node_num++;
}
if (fast) // 奇數個結點
{
node_num = node_num * 2 + 1;
}
else // 偶數個結點
{
node_num = node_num * 2;
}
int reverse_time = node_num / k; // 需要翻轉連結串列的次數
// 連結串列結點數小於 k,不需要翻轉連結串列
if (reverse_time == 0)
{
return head;
}
else
{
ListNode* temp = head; // 儲存連結串列的頭結點
ListNode* tail = head; // 翻轉後子連結串列的尾結點
ListNode* p1 = head;
ListNode* p2 = head;
ListNode* p3 = NULL;
for (int i = 0; i < reverse_time; i++)
{
p2 = p2->next;
// 進行 k-1 次翻轉
for (int j = 0; j < k-1; j++)
{
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}
if (i == 0)
{
temp = p1; // 第一輪翻轉,temp 指向翻轉後的新連結串列的頭結點
}
else
{
tail->next = p1; // 連線翻轉後的子連結串列
}
tail = head; // 指向翻轉後的新連結串列的尾結點
head = p2; // 指向後面待翻轉連結串列的第一個結點
p1 = p2;
}
tail->next = head; // 連線多餘的結點
return temp;
}
}
}
};
獲取更多精彩,請關注「seniusen」!