1. 程式人生 > 實用技巧 >考的最多的LeetCode hard難度演算法 --- k個一組翻轉連結串列

考的最多的LeetCode hard難度演算法 --- k個一組翻轉連結串列

給你一個連結串列,每k個節點一組進行翻轉,請你返回翻轉後的連結串列。

k是一個正整數,它的值小於或等於連結串列的長度。

如果節點總數不是k的整數倍,那麼請將最後剩餘的節點保持原有順序。

示例:

給你這個連結串列:1->2->3->4->5

當k= 2 時,應當返回: 2->1->4->3->5

當k= 3 時,應當返回: 3->2->1->4->5

說明:你的演算法只能使用常數的額外空間。 你不能只是單純的改變節點內部的值,而是需要實際進行節點交換。

這道題雖然是hard難度,而且通過率也很高,在各種面經上也常出現,因此寫下來做備忘。
其實對於連結串列的演算法題,建立哨兵頭結點+頭插法這個組合就能解決絕大部分了,這道題也不例外。

另外做連結串列類演算法題時,可以多定義幾個臨時變數,讓自己思路清晰也能大大降低連結串列連接出錯的概率

public ListNode reverseKGroup(ListNode head, int k) {
        ListNode myHead = new ListNode(0);

        //pre為頭插法的頭節點
        ListNode pre = myHead;
        //start為實際插入的節點
        ListNode start = head;
        boolean stop=false;
        for (; ; ) {
            //檢查剩餘是否有k個節點可以翻轉,如果沒有直接break
            if (start == null) break;
            ListNode check = start;
            for (int i = 0; i < k - 1; i++) {
                check = check.next;
                if (check == null){
                    stop=true;
                    break;
                }
            }
            if(stop)break;
            //頭插法翻轉k個一組的節點
            for (int i = 0; i < k; i++) {

                ListNode startNext = start.next;
                ListNode preNext = pre.next;
                pre.next = start;
                start.next = preNext;
                start = startNext;

            }
            //pre前進k次
            for (int i = 0; i < k; i++) {
                pre = pre.next;
            }

        }
        //把剩餘不足k個的節點連線上去
        while (start != null) {
            pre.next = start;
            pre = pre.next;
            start = start.next;
        }

        return myHead.next;
    }