K 個一組翻轉鏈表(leetcode24,25)題解

題目25,24:

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

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

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

示例 :

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

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

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

說明 :

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

題解:

這個題在leetcode屬於困難型,對於這個題的解法可以這樣想:
首先,對一個鏈表的翻轉我們肯定很熟悉,那麼k個一組不就是翻轉k個鏈表嘛,不過是翻轉之前需要將未翻轉的標記一下next,翻轉了過後再將第一個鏈表的尾節點start.next = next,然後在循環進行下一個鏈表的翻轉,直接將翻轉封裝成一個方法reverse(ListNode start)。在翻轉的時候爲了讓頭節點也有前驅,我們自己定義一個headHead,如圖所示:
一次翻轉結束,更新pre end,start,end進行下一次翻轉,如果end爲到達指定的長度就結束了,說明節點數不夠了嘛,然後就不用翻轉了。整個操作空間複雜度O(1),常數額外空間,時間複雜度O(n*k),在題解中還看到一種優化說不用判斷最後一個鏈表的長度,直接翻轉就完了,如果最後發現長度不夠再翻轉回來,各位可以試試。
在這裏插入圖片描述

給出我的結果以及代碼:
在這裏插入圖片描述

public ListNode reverseKGroup(ListNode head, int k) {
	//如果爲空,或者只有一個節點,直接返回嘛
        if (head == null || head.next == null){
                return head;
        }

//給頭節點一個前驅,不用單獨爲頭節點考慮了
        ListNode headHead = new ListNode(-1);
        headHead.next = head;
        ListNode pre = headHead;
        ListNode end = headHead;
        while (end.next != null){
            //end移動到末尾
            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);
            //末尾要連接到下一個連接的next,
            start.next = next;
            pre = start;
            end = start;
        }
        return headHead.next;
    }


    //翻轉鏈表
    private ListNode reverse(ListNode start) {
        if (start == null || start.next == null){
            return start;
        }
        ListNode p = start;
        ListNode q = start.next;
        while (q != null){
            ListNode t = q.next;
            q.next = p;
            p = q;
            q = t;
        }
        start.next = null;
        return p;
    }```

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章