考的最多的LeetCode hard難度演算法 --- k個一組翻轉連結串列
阿新 • • 發佈:2020-11-18
給你一個連結串列,每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; }