【LeetCode刷題】將兩個升序鏈表合並為一個新的升序鏈表


題記

轉眼已過去很多年了,登錄園子看到幾年前自己記錄的筆記,感慨萬千,慶幸的是自己還在這行沒有放棄,不過,隨着工作經驗的積累,感覺自己越來越無知,索性最近又撿起9年前剛畢業工作那會兒無知的勁兒,來刷題換換腦子~~~

題目描述

該題來自LeetCode第21題:合並兩個有序鏈表
https://leetcode-cn.com/problems/merge-two-sorted-lists/

將兩個升序鏈表合並為一個新的 升序 鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。

示例:
輸入:l1 = [1,2,4], l2 = [1,3,4]
輸出:[1,1,2,3,4,4]

image

解題思路

  1. 創建一個虛擬頭節點,其下一個節點為從L1, L2的頭節點中選取值較小的節點,假設合並完成,則返回輔助節點的下一個節點,即為最終鏈表的頭節點;
  2. 新建一個輔助節點,比較L1, L2當前節點的值,其下一個節點也指向L1, L2中值較小的節點,向后移動較小值的節點,同時輔助節點也后移一位;
  3. 重復第2步,直至L1, L2其中一個鏈表遍歷完成, 輔助節點的下一個節點指向剩下未遍歷完成的鏈表即可。

總結下來,其實就像是拿着一個針(輔助節點)穿珠子,比較兩串珠子頭上一顆珠子的大小,把小的穿上(輔助節點的下一個節點指向二者小的節點),重復該動作,到其中一串珠子穿完,剩下的無需比較直接穿到后面即可。

通過文字描述還是比較抽象,通過畫圖的形式來演示每一步,相對來說,就比較好理解了,我按照上述步驟畫了一下推演圖,如下:

  1. compare比較鏈表頭節點大小
  2. pre下一個節點指向值小的鏈表
  3. 較小的鏈表頭向后移動一位
  4. pre也向后移動一位(指向合並后的鏈表尾節點)

image

Java代碼實現

public class MergeTwoLists {

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
        // 虛擬頭節點,下一個節點指向L1,L2二者中較小的頭節點
        ListNode preHead = new ListNode(-1);
        // 輔助節點引用
        ListNode pre = preHead;
        while (l1 != null && l2 != null) {
            // 輔助節點的下一個節點為值小的節點
            // 較小值的節點向后移動
            if (l1.val > l2.val) {
                pre.next = l2;
                l2 = l2.next;
            } else {
                pre.next = l1;
                l1 = l1.next;
            }
            // 輔助節點也同步向后移動
            pre = pre.next;
        }
        // 如果其中一個鏈表已經結束,則剩下節點接到后面即可
        pre.next = l1 == null ? l2 : l1;
        // 返回虛擬頭節點的下一個節點
        return preHead.next;
    }
}

總結

該解法的時間復雜度為O(m+n), m、n分別為鏈表L1、L2的長度;空間復雜度為 O(1), 引入了輔助節點,沒有利用其它額外的空間。另外,還有另外一種解法是遞歸,俗話說,遞歸是一看就會,一寫就跪,等有空了再試試。

結束...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM