算法設計與分析 第十二週 k個一組翻轉鏈表


1 題目描述

在這裏插入圖片描述


2 選題原因

講道理這個周確實沒講啥東西…秉承着隨機的原則,在首頁閉着眼睛點了一下鼠標,選中了這道題。


3 題目分析及算法

3.1 常規分析

分析這道題目,其實是比較簡單的。涉及的操作無非就是節點的轉移,思考清楚就沒有太大的難度。
看這道題,說白了就是將不同段的節點顛倒過來,其實實現起來很簡單。我們先看一段鏈表的倒置

在這裏插入圖片描述

當我們要倒置的時候,應該是從頭節點開始,依次將頭節點放在最後。例如上圖,我們從1開始,先使用一個指針指向2,接着將1節點放在隊列的最後(該節點下一個節點稍後會說),接着,將頭節點更新爲指針指向的節點(即節點2)。

算法如下:
FOR i = 1: k
temp = head -> next;
head -> next = tail;
tail = head;
ENDFOR

3.2 問題所在

接下來,我們要考慮的問題是:先調換前面的組還是先調換後面的組。
仔細觀察一下。當前組的首節點會被放在最後,和下一個組的首節點相接,而下一組的首節點是什麼?取決於我們的調換順序。如果我們從前往後調換,那麼這一組會在下一組首節點被放在最後之前連接上!而如果我們從後往前調換,就會在下一組調換完成連接上節點,也正是正常順序!


4 關鍵代碼

4.1 組內節點調換

            //反轉節點
            while (count > 0) {
                //next 下一個頭節點
                //next_head 下一個要放在最後的節點
                ListNode* next = head->next;
                head->next = next_head;
                next_head = head;
                head = next;
                count--;
            }

4.2 遞歸的從後向前調換

        while (next_head != NULL && count != k) {
            next_head = next_head->next;
            count++;
        }
        //遞歸後面的組先反轉,用反轉後新的頭作爲自己尾節點的下一個節點
        if (count == k) {
            next_head = reverseKGroup(next_head, k);
        }

5 運行結果

在這裏插入圖片描述


6 源代碼

/**
 * 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) {
        ListNode* next_head = head;                 //標記下一組要反轉的位置
        int count = 0;                              //標記當前組的節點數
        //找到下一組節點
        while (next_head != NULL && count != k) {
            next_head = next_head->next;
            count++;
        }
        //遞歸後面的組先反轉,用反轉後新的頭作爲自己尾節點的下一個節點
        if (count == k) {
            next_head = reverseKGroup(next_head, k);

            //反轉節點
            while (count > 0) {
                //next 下一個頭節點
                //next_head 下一個要放在最後的節點
                ListNode* next = head->next;
                head->next = next_head;
                next_head = head;
                head = next;
                count--;
            }
            //指向新的頭
            head = next_head;
        }
        return head;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章