【每日一題-leetcode】25.reverse-nodes-in-k-group

25.K 個一組翻轉鏈表

難度困難416

給你一個鏈表,每 *k *個節點一組進行翻轉,請你返回翻轉後的鏈表。

*k *是一個正整數,它的值小於或等於鏈表的長度。

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

示例:

給你這個鏈表:1->2->3->4->5

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

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

說明:

  • 你的算法只能使用常數的額外空間。
  • 你不能只是單純的改變節點內部的值,而是需要實際進行節點交換。
 /***
         * 迭代法
         * 1.鏈表分區已翻轉 + 待翻轉 + 未翻轉部分
         * 2.翻轉前確定翻轉的範圍 通過k來決定
         * 3.記錄鏈表前驅和後繼 方便翻轉完成後,把已翻轉和未翻轉連接起來。
         * 4.初始化兩個邊路pre  end  pre >代表待翻轉鏈表的前驅,end代表待翻轉的末尾。
         * 5.經過k次 end到達鏈表末尾。  記錄待翻轉鏈表的後繼 next = end.next
         * 6.翻轉鏈表,將三部分連接起來,然後重置pre 和 end 指針 進入下一個循環
         * 7.特殊情況 翻轉部分長度不足k時,在定位end 完成後,end = null 已經到達末尾。
         * 8.時間複雜度爲 O(n*K) 最好的情況爲 O(n) 最差的情況未 O(n^2)
         * 9.空間複雜度爲 O(1)
         * @param head
         * @param k
         * @return
         */
        public ListNode reverseKGroup(ListNode head, int k) {
            ListNode dumy = new ListNode(0);
            dumy.next = head;
    
            ListNode pre = dumy;
            ListNode end = dumy;
    
            while (end.next != null) {
                //確定待翻轉的範圍
                for (int i = 0; i < k && end != null; i++) {
                    end = end.next;
                }
    
                if (end == null) {
                    break;
                }
    
                ListNode start = pre.next;//待翻轉鏈表的開始位置
                ListNode next = end.next;//下一個待翻轉鏈表的起始位置
    
                end.next = null;//和後繼待翻轉鏈表斷開
    
                pre.next = reverse(start);
                start.next = next;
                pre = start;
    
                end = pre;
            }
            return dumy.next;
        }
    
        public static ListNode reverse(ListNode head) {
            ListNode pre = null;
            ListNode curr = head;
            //假設 1 -> 2 -> 3
            while (curr != null) {
                ListNode next = curr.next; // next = 2   // next = 3
                curr.next = pre;// 1.next = null        // 3.next = 1
                pre = curr;// pre = 1;                 //  1 = 3
                curr = next; // curr = 2              // 3  = null
            }
            return pre; //
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章