【LeetCode 熱題 100】23. 合并 K 個升序鏈表——(解法一)逐一合并

Problem: 23. 合并 K 個升序鏈表
題目:給你一個鏈表數組,每個鏈表都已經按升序排列。
請你將所有鏈表合并到一個升序鏈表中,返回合并后的鏈表。

文章目錄

  • 整體思路
  • 完整代碼
  • 時空復雜度
    • 時間復雜度:O(K * N)
    • 空間復雜度:O(1)

整體思路

這段代碼旨在解決一個經典的鏈表問題:合并 K 個排序鏈表 (Merge K Sorted Lists)。問題要求將一個包含 K 個已排序鏈表的數組,合并成一個單一的、大的有序鏈表。

該實現采用了一種簡單直接的 逐一合并 (One by One Merging) 的策略。它將“合并K個鏈表”的問題,簡化為了“重復執行 K-1 次‘合并兩個鏈表’”的問題。

其核心邏輯步驟如下:

  1. 處理邊界情況

    • 首先,檢查輸入的鏈表數組 lists 是否為 null 或空。如果是,直接返回 null
    • 如果數組中只有一個鏈表,直接返回該鏈表。
  2. 迭代合并

    • 算法將 lists[0] 作為“累加器”或“基準鏈表”。
    • 通過一個 for 循環,從 i=1 開始,依次將 lists[i] 合并到 lists[0] 中。
    • lists[0] = merge(lists[0], lists[i]); 這一行是核心。它調用一個輔助函數 merge,將當前的合并結果 lists[0] 與下一個鏈表 lists[i] 進行合并,然后用新的、更長的合并結果來更新 lists[0]
    • 這個過程會重復 K-1 次。
  3. merge 輔助函數

    • 這個私有函數 merge(l1, l2) 是一個標準的“合并兩個有序鏈表”的實現。
    • 它使用哨兵節點 dummy 和一個 cur 指針,通過迭代比較 l1l2 的節點值,將較小的節點鏈接到結果鏈表的末尾,直到其中一個鏈表被遍歷完。
    • 最后,將另一個鏈表中剩余的部分直接追加到結果鏈表的末尾。
    • 這個函數在每次主循環中被調用。
  4. 返回結果

    • for 循環結束后,lists[0] 中就存儲了所有 K 個鏈表合并后的最終結果,將其返回。

雖然這個方法邏輯清晰,易于理解,但它并不是最高效的解決方案,因為在合并過程中存在大量的重復比較。

完整代碼

/*** Definition for singly-linked list.*/
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}class Solution {/*** 合并 K 個排序鏈表。* @param lists 一個包含 K 個排序鏈表的數組* @return 合并后的單一排序鏈表*/public ListNode mergeKLists(ListNode[] lists) {// 處理邊界情況:輸入為空或沒有鏈表if (null == lists || lists.length == 0) {return null;}int n = lists.length;// 如果只有一個鏈表,直接返回它if (1 == n) {return lists[0];}// 步驟 1: 逐一合并// 將 lists[0] 作為基礎,依次將 lists[1], lists[2], ... 合并進來for (int i = 1; i < n; i++) {// 調用輔助函數合并當前的累積結果 lists[0] 和下一個鏈表 lists[i]lists[0] = merge(lists[0], lists[i]);}// 循環結束后,lists[0] 就是最終的合并結果return lists[0];}/*** 輔助函數:合并兩個有序鏈表。* @param l1 第一個有序鏈表* @param l2 第二個有序鏈表* @return 合并后的有序鏈表*/private ListNode merge(ListNode l1, ListNode l2) {// 使用哨兵節點簡化合并邏輯ListNode dummy = new ListNode();ListNode cur = dummy;// 比較兩個鏈表的節點,將較小的鏈接到結果鏈表while (null != l1 && null != l2) {if (l1.val < l2.val) {cur.next = l1;l1 = l1.next;} else {cur.next = l2;l2 = l2.next;}cur = cur.next;}// 將剩余的鏈表部分直接追加到末尾cur.next = null == l1 ? l2 : l1;return dummy.next;}
}

時空復雜度

時間復雜度:O(K * N)

  1. merge 函數的復雜度:合并兩個長度分別為 mn 的鏈表,時間復雜度是 O(m + n)。
  2. 主循環分析
    • K 是鏈表的數量,N 是所有鏈表的節點總數。為簡化分析,我們假設每個鏈表平均有 N/K 個節點。
    • 第一次合并 (i=1): merge(lists[0], lists[1])lists[0] 長度為 N/Klists[1] 長度為 N/K。耗時 O(2N/K)。合并后 lists[0] 長度變為 2N/K
    • 第二次合并 (i=2): merge(lists[0], lists[2])lists[0] 長度為 2N/Klists[2] 長度為 N/K。耗時 O(3N/K)。合并后 lists[0] 長度變為 3N/K
    • i 次合并: lists[0] 長度為 i * (N/K)lists[i] 長度為 N/K。耗時 O((i+1)N/K)。
    • 總時間Σ(i=1 to K-1) (i+1)N/K = (N/K) * Σ(j=2 to K) j = (N/K) * (K(K+1)/2 - 1)
    • 這個表達式的最高階項是 (N/K) * (K^2 / 2),所以復雜度是 O(N * K)

綜合分析
該算法的時間復雜度為 O(N * K),其中 N 是總節點數,K 是鏈表數。當 K 較大時,這個效率并不理想。

空間復雜度:O(1)

  1. 主要存儲開銷
    • merge 函數內部使用了 dummycur 等常數個指針變量。
    • 主函數 mergeKLists 也沒有使用與 NK 成比例的額外數據結構。它是在原地修改 lists 數組的第一個元素。

綜合分析
算法所需的額外輔助空間是常數級別的。因此,其空間復雜度為 O(1)。這是該解法的一個優點。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88782.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88782.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88782.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

垃圾收集器-Serial Old

第一章 引言1.1 JVM 中垃圾收集的簡要概述JVM&#xff08;Java Virtual Machine&#xff09;作為 Java 程序的運行時環境&#xff0c;負責將字節碼加載至內存并執行&#xff0c;同時也承擔著內存管理的重任。垃圾收集&#xff08;Garbage Collection&#xff0c;簡稱 GC&#x…

Docker(02) Docker-Compose、Dockerfile鏡像構建、Portainer

Docker-Compose 1、Docker Desktop 在Windows上安裝Docker服務&#xff0c;可以使用Docker Desktop這個應用程序。 下載并安裝這樣的一個安裝包 安裝好后&#xff1a;執行命令 docker --version 從Docker Hub提取hello-world映像并運行一個容器&#xff1a; docker run h…

大數據時代UI前端的用戶體驗設計新思維:以數據為驅動的情感化設計

hello寶子們...我們是艾斯視覺擅長ui設計和前端數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;從 “經驗設計” 到 “數據共情” 的體驗革命傳統 UI 設計常陷入 “設計師主觀經…

TypeScript 學習手冊

1.TypeScript 概念 TypeScript&#xff08;簡稱 TS&#xff0c;靜態類型&#xff09;是微軟公司開發的一種基于 JavaScript &#xff08;簡稱 JS&#xff0c;動態類型&#xff09;語言的編程語言。TypeScript 可以看成是 JavaScript 的超集&#xff08;superset&#xff09;&a…

掌握現代CSS:變量、變形函數與動態計算

CSS近年來發展迅速&#xff0c;引入了許多強大的功能&#xff0c;如變量、高級變形函數和動態計算能力。本文將深入探討如何在CSS中設置并使用變量&#xff0c;以及如何有效利用translate3d、translateY和translateX等變形方法。我們還將解析var()和calc()函數的關鍵作用。一、…

貝爾量子實驗設想漏洞

1 0 1 0 1 1 0 1 0 1 1 1 0 0 1 0 帶墨鏡如果先上下交換再左右交換&#xff0c;很可能不一樣的概率是2%&#xff0c;但是因為交換誕生了一個與之前序列相同的所以不一樣概率變成1%&#xff0c;我們在測的時候不能這么測啊&#xff0c;你得看序列完…

在 Android 庫模塊(AAR)中,BuildConfig 默認不會自動生成 VERSION_CODE 和 VERSION_NAME 字段

為什么AAR庫模塊的 BuildConfig 沒有 versionCode 和 versionName&#xff1f; aar庫模塊的 BuildConfig 默認不包含版本信息 應用模塊&#xff08;com.android.application&#xff09;會自動生成 versionCode 和 versionName 到 BuildConfig。但庫模塊&#xff08;com.androi…

強化學習 (11)隨機近似

計算均值的新方法有兩種方法。第一種方法很直接&#xff0c;即收集所有樣本后計算平均值&#xff1b;但這種方法的缺點是&#xff0c;若樣本是在一段時間內逐個收集的&#xff0c;我們必須等到所有樣本都收集完畢。第二種方法可避免此缺點&#xff0c;因為它以增量迭代的方式計…

PHP `implode` 深度解析:從基礎到高階實戰指南

文章目錄一、基礎語法與底層原理執行過程解析&#xff1a;二、性能關鍵&#xff1a;避免隱含陷阱1. 類型轉換黑盒2. 大數組內存優化3. 關聯數組處理三、高階應用場景1. SQL語句安全構建2. CSV文件生成3. 模板引擎實現四、多維數組處理方案1. 遞歸降維2. JSON轉換橋接五、性能對…

開發語言中關于面向對象和面向過程的筆記

開發語言中關于面向對象和面向過程的筆記市面主流語言分類面向過程面向對象市面主流語言分類 面向過程編程&#xff08;Procedural Programming&#xff09;&#xff1a;C語言&#xff1b;面向對象編程語言&#xff08;Object-Oriented Programming, OOP&#xff09; &#xf…

AI產品經理面試寶典第3天:技術分層、邊界與市場全景系列面試題

面試指導 面試官:請從技術實現效果的角度,解釋AI技術分層。 你的回答: AI技術分為三層。 第一層是認知層:通過圖像處理、語音識別、自然語言理解等技術,讓機器感知環境。比如攝像頭識別行人動作,麥克風捕捉用戶指令。 第二層是預測層:基于行為數據預判下一步需求。例如…

Intel英特爾ICH7R/ICH8R/ICH9R/ICH10R系列下載地址--intel_msm_8961002 下載 Version 8.9.6.1002

Intel英特爾ICH7R/ICH8R/ICH9R/ICH10R系列下載地址intel_msm_8961002 下載 Version 8.9.6.1002https://xiazai.zol.com.cn/detail/66/653449.shtml通過網盤分享的文件&#xff1a;intel_msm_8961002.zip 鏈接: https://pan.baidu.com/s/13N9ZLXWkaWaEHQ5P90Jt0g?pwd3790 提取碼…

AI(學習筆記第五課) 使用langchain進行AI開發 load documents(web)

文章目錄AI(學習筆記第五課) 使用langchain進行AI開發 load documents(web)學習內容&#xff1a;1.load documents&#xff08;web&#xff09;1.1 學習url1.2 提前安裝python的package1.2 使用WebBaseLoader進行webpage的load1.3 使用BeautifulSoup4進行webpage的部分截取1.4 …

使用macvlan實現容器的跨主機通信

使用環境&#xff1a; 兩臺運行docker的服務器 A機器網段&#xff1a;192.168.86.61 B機器網段&#xff1a;192.168.86.62 運行的容器需裝有ping指令&#xff0c; 實驗參數解釋&#xff1a; -d macvlan 指定創建網絡驅動類型 --subnet 指定子網范圍 -gateway 指定網關地址 -o p…

深度學習_全連接神經網絡

1.什么是神經網絡神經網絡中信息只向一個方向移動&#xff0c;即從輸入節點向前移動&#xff0c;通過隱藏節點&#xff0c;再向輸出節點移 動&#xff0c;網絡中沒有循環或者環。其中的基本構件是&#xff1a; 輸入層&#xff1a;即輸入x的那一層 輸出層&#xff1a;即輸出y的那…

OpenLayers使用

初學ol&#xff0c;實現了高德地圖不同圖層的切換、交互性地圖飛行以及加載本地JSON數據。說一下不同圖層切換的想法&#xff1a;1.對于標準地圖和衛星地圖&#xff1a;二者最初便掛載到map上&#xff0c;兩個圖層是疊加顯示的&#xff1b;當點擊按鈕時&#xff0c;其實是使用 …

day4--上傳圖片、視頻

1. 分布式文件系統 1.1 什么是分布式文件系統 文件系統是負責管理和存儲文件的系統軟件&#xff0c;操作系統通過文件系統提供的接口去存取文件&#xff0c;用戶通過操作系統訪問磁盤上的文件。 下圖指示了文件系統所處的位置&#xff1a; 常見的文件系統&#xff1a;FAT16/FA…

極矢量與軸矢量

物理量分為標量和矢量&#xff0c;矢量又分為極矢量和軸矢量。 矢量是既有大小又有方向并按平行四邊形法則相加的量。矢量有極矢量和軸矢量兩種&#xff0c;其間的區別是在鏡像反射變換下遵循不同的變換規律,許多物理量都是矢量,同樣,其中也有極矢量和軸矢量的區分,在力學中,例…

文章發布易優CMS(Eyoucms)網站技巧

為了更快的上手數據采集及發布到易優CMS(eyoucms)網站&#xff0c;特地總結了些新手常常會遇到的操作問題與技巧&#xff0c;如下&#xff1a; 免費易優CMS采集發布插件下載&#xff0c;兼容火車頭、八爪魚、簡數采集等 目錄 1. 發布到易優CMS指定欄目 2. 發布文章到易優CM…

INA226 數據手冊解讀

INA226是一款數字電流檢測放大器&#xff0c;配備I2C和SMBus兼容接口。該器件可提供數字電流、電壓以及功率讀數&#xff0c;可靈活配置測量分辨率&#xff0c;并具備連續運行與觸發操作模式。該芯片通常由一個單獨的電源供電&#xff0c;電壓范圍為 2.7V 至 5.5V引腳說明??引…