合并兩個有序鏈表:遞歸與迭代的實現分析

合并兩個有序鏈表:遞歸與迭代的實現分析

在算法與數據結構的世界里,鏈表作為一種基本的數據結構,經常被用來解決各種問題。特別是對于有序鏈表的合并,既是經典面試題,也是提高編程能力的重要練習之一。合并兩個有序鏈表,看似簡單,但通過遞歸和迭代兩種方式實現,我們可以深入了解不同算法思想的應用和其性能差異。今天,我將圍繞這一經典問題,從遞歸和迭代兩種方法進行分析與實現,幫助大家更好地理解鏈表操作背后的算法思想。

1. 問題描述

給定兩個有序鏈表l1l2,它們的元素都是升序排列的,合并這兩個鏈表并返回一個新的有序鏈表。我們可以利用兩種不同的方法來解決這一問題:遞歸和迭代。

2. 鏈表的基本結構

首先,我們需要知道鏈表的基本結構。在大多數編程語言中,鏈表通常由節點組成,每個節點包含一個值和指向下一個節點的指針。

class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = next

ListNode類代表鏈表中的一個節點,每個節點包含一個值(val)和指向下一個節點的指針(next)。next指針指向下一個節點,如果當前節點是鏈表的最后一個節點,則nextNone

3. 遞歸實現:分治的巧妙應用

遞歸是一種將問題分解為更小的子問題的算法思想。對于合并兩個有序鏈表,我們可以將其看作一個遞歸問題:每次遞歸選擇兩個鏈表的頭節點中較小的一個,繼續合并剩下的部分。

3.1 遞歸實現代碼
def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode:# 基礎情況:如果一個鏈表為空,直接返回另一個鏈表if not l1:return l2if not l2:return l1# 選擇較小的節點,遞歸地合并剩余部分if l1.val < l2.val:l1.next = mergeTwoLists(l1.next, l2)return l1else:l2.next = mergeTwoLists(l1, l2.next)return l2
3.2 遞歸實現分析
  1. 基本情況:首先,我們要處理遞歸的基本情況。當l1為空時,說明l1鏈表已合并完成,直接返回l2;當l2為空時,同理,直接返回l1
  2. 遞歸合并:每次遞歸,我們比較l1l2的頭節點,選擇較小的一個節點,將它的next指向合并后的結果。遞歸調用合并剩余部分的鏈表。
  3. 時間復雜度:遞歸實現的時間復雜度是O(m + n),其中mn分別是兩個鏈表的長度,因為每個鏈表的節點都會被訪問一次。
  4. 空間復雜度:遞歸需要棧空間來保存每次遞歸的狀態,最壞情況下(鏈表很長),遞歸棧的深度是O(m + n)。
3.3 遞歸實現優缺點
  • 優點:代碼簡潔、直觀,遞歸的思想非常符合分治法的精神。
  • 缺點:遞歸調用會導致棧的使用,棧深度可能較大,導致內存消耗較高,尤其在鏈表較長時,可能會發生棧溢出。

4. 迭代實現:一步步推進的非遞歸方式

如果你想避免遞歸帶來的棧空間問題,可以采用迭代的方式來實現合并。這種方法通過顯式地使用一個指針來跟蹤合并后的鏈表的尾部,避免了遞歸的空間消耗。

4.1 迭代實現代碼
def mergeTwoListsIterative(l1: ListNode, l2: ListNode) -> ListNode:# 創建一個啞節點,方便操作dummy = ListNode()current = dummy# 迭代合并兩個鏈表while l1 and l2:if l1.val < l2.val:current.next = l1l1 = l1.nextelse:current.next = l2l2 = l2.nextcurrent = current.next# 處理剩余部分(如果有的話)if l1:current.next = l1elif l2:current.next = l2return dummy.next
4.2 迭代實現分析
  1. 初始化:我們創建一個dummy節點,這個節點是一個啞節點(即不存儲任何有效數據的節點),它的作用是簡化代碼的書寫,避免處理頭節點為空的情況。current指針指向當前合并鏈表的最后一個節點。
  2. 迭代過程:我們通過while循環不斷比較l1l2的頭節點,選擇較小的節點并將它連接到current節點的后面。每次選擇一個節點后,我們都更新current指針。
  3. 處理剩余節點:當l1l2有一個鏈表已經為空時,我們直接將另一個鏈表剩余的部分連接到合并鏈表的末尾。
  4. 時間復雜度:與遞歸方法類似,迭代的時間復雜度也是O(m + n),其中mn是兩個鏈表的長度。
  5. 空間復雜度:迭代實現只需要O(1)的額外空間,除了合并后的鏈表外,沒有額外的棧空間開銷。
4.3 迭代實現優缺點
  • 優點:相比遞歸,迭代的空間復雜度更低,因為沒有遞歸棧的消耗。它適用于鏈表較長的情況。
  • 缺點:代碼相對遞歸稍微復雜,需要手動維護current指針和dummy節點。

5. 遞歸與迭代的對比

特性遞歸實現迭代實現
實現復雜度較為簡潔,符合分治思想稍微復雜,手動控制指針
空間復雜度O(m + n)(遞歸棧深度)O(1)(常數空間)
時間復雜度O(m + n)O(m + n)
適用場景小規模數據時,優雅簡潔大規模數據時,避免棧溢出

6. 總結

合并兩個有序鏈表看似簡單,但通過遞歸和迭代兩種方式實現,我們可以發現不同算法的設計思想與性能差異。遞歸實現代碼簡潔,但棧深度可能成為性能瓶頸;而迭代實現則在空間復雜度上更為優秀,適用于較長鏈表的合并。

在實際開發中,選擇遞歸或迭代實現主要取決于問題的規模和對性能的需求。如果問題規模較小且追求代碼簡潔,遞歸是一個不錯的選擇;但如果數據量較大,迭代方式可能更為合適,避免了遞歸帶來的棧空間壓力。通過這兩種方法的實踐,大家不僅能掌握合并兩個有序鏈表的基本操作,還能深入理解遞歸與迭代的優缺點,為解決其他復雜問題奠定基礎。

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

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

相關文章

破解密碼防線:滲透測試中的密碼攻擊手法匯總

密碼是網絡安全中的一道重要防線&#xff0c;然而&#xff0c;若密碼策略不嚴密&#xff0c;往往會為攻擊者提供可乘之機。本文將簡要介紹滲透測試中關于密碼的幾種常見攻擊思路和手法。 1. 確認使用默認及常見的賬號密碼 在滲透測試的初期&#xff0c;攻擊者通常會嘗試使用系…

CSS Selectors

當然&#xff0c;理解純CSS選擇器&#xff08;CSS Selectors&#xff09;對于進行UI自動化測試非常重要。CSS選擇器允許您通過元素的屬性、層級關系、類名、ID等來精準定位頁面上的元素。下面我將詳細講解CSS選擇器的常見用法&#xff0c;并結合您的需求提供具體的示例。 1. 基…

【java】@Transactional導致@DS注解切換數據源失效

最近業務中出現了多商戶多租戶的邏輯&#xff0c;所以需要分庫&#xff0c;項目框架使用了mybatisplus所以我們自然而然的選擇了同是baomidou開發的dynamic.datasource來實現多數據源的切換。在使用初期程序運行都很好&#xff0c;但之后發現在調用com.baomidou.mybatisplus.ex…

淺入淺出Selenium DevTools

前言 在自動化測試領域&#xff0c;Selenium一直是主流工具之一。隨著前端技術的不斷發展&#xff0c;瀏覽器的功能也在不斷豐富。 Selenium 3版本前&#xff0c;一套通用的采集流程如上圖所示&#xff1a; 打開Charles&#xff0c;設置Session自動導出頻次及導出路徑Seleniu…

04 路由表的IP分組傳輸過程

目錄 1、路由表的核心結構 2、IP分組傳輸過程和數據包轉發過程 2.1、IP分組傳輸過程 2.2、數據包轉發過程 2.3、IP分組傳輸過程和數據包轉發的區別 3、數據包的變化 3.1、拓撲結構 3.2、傳輸過程詳解&#xff08;主機A → 主機B&#xff09; 3.2.1、主機A發送數據 3.2…

【子網掩碼計算器:Python + Tkinter 實現】

子網掩碼計算器&#xff1a;Python Tkinter 實現 引言代碼功能概述代碼實現思路1. 界面設計2. 功能實現3. 事件處理 子網掩碼計算器實現步驟1. 導入必要的庫2. 定義主窗口類 SubnetCalculatorApp3. 創建菜單欄4. 創建界面組件5. 判斷 IP 地址類別6. 計算子網信息7. 其他功能函…

【練習】【貪心】力扣1005. K 次取反后最大化的數組和

題目 1005 K 次取反后最大化的數組和 給你一個整數數組 nums 和一個整數 k &#xff0c;按以下方法修改該數組&#xff1a; 選擇某個下標 i 并將 nums[i] 替換為 -nums[i] 。 重復這個過程恰好 k 次。可以多次選擇同一個下標 i 。 以這種方式修改數組后&#xff0c;返回數組 可…

3dsmax中使用python創建PBR材質并掛接貼圖

前言 筆者處理模型時下載到一個pbr材質庫貼圖包&#xff0c;手動每次創建材質過于麻煩&#xff0c;因此計劃使用自動化腳本根據貼圖名自動創建材質。 3dsmax的原本腳本使用的是maxscript&#xff0c;語法有點奇怪懶得學&#xff0c;發現也支持使用python編寫腳本&#…

Metal學習筆記九:光照基礎

光和陰影是使場景流行的重要要求。通過一些著色器藝術&#xff0c;您可以突出重要的對象、描述天氣和一天中的時間并設置場景的氣氛。即使您的場景由卡通對象組成&#xff0c;如果您沒有正確地照亮它們&#xff0c;場景也會變得平淡無奇。 最簡單的光照方法之一是 Phong 反射模…

JAVA學習筆記038——bean的概念和常見注解標注

什么是bean? Bean 就是 被 Spring 管理的對象&#xff0c;就像工廠流水線上生產的“標準產品”。這些對象不是你自己 new 出來的&#xff0c;而是由 Spring 容器&#xff08;一個超級工廠&#xff09;幫你創建、組裝、管理。 由 Component、Service、Controller 等注解標記的…

start DL from stratch (2)!!!

start DL from stratch &#xff08;2&#xff09;!!! 一、CPU and GPUcpuGPU安培架構愛達洛夫萊斯架構 二、使用conda創建一個新的虛擬環境三、autodl操作先知Linux復習目錄文件和數據上傳對于整個鏡像的操作守護進程Tips 四、autodl租用創建實例<big>沒有所需要的版本的…

機器學習:線性回歸,梯度下降

線性回歸模型 (Linear Regression Model) 梯度下降算法 (Gradient Descent Algorithm) 的數學公式

論文筆記-NeurIPS2017-DropoutNet

論文筆記-NeurIPS2017-DropoutNet: Addressing Cold Start in Recommender Systems DropoutNet&#xff1a;解決推薦系統中的冷啟動問題摘要1.引言2.前言3.方法3.1模型架構3.2冷啟動訓練3.3推薦 4.實驗4.1實驗設置4.2在CiteULike上的實驗結果4.2.1 Dropout率的影響4.2.2 實驗結…

nvm的學習

學習 nvm&#xff08;Node Version Manager&#xff09; 是掌握 Node.js 開發的關鍵技能之一。以下是系統的學習路徑和實戰指南&#xff0c;涵蓋從基礎到進階的內容&#xff1a; 一、基礎入門 1. nvm 的核心作用 多版本共存&#xff1a;安裝和管理多個 Node.js 版本&#xff…

GPT-4.5實際性能評測:實際探索

摘要 經過數萬輪嚴格測試&#xff0c;GPT-4.5的性能并未超越其前代產品GPT-4。此前發布的《GPT-4.5 一手實測&#xff1a;垃圾》一文中存在不準確描述&#xff0c;在此向讀者致歉。盡管GPT-4.5在價格上有所提升且響應速度較慢&#xff0c;但測試結果顯示其模型素質并未達到預期…

從UNIX到Linux:操作系統進化史與開源革命

從UNIX到Linux&#xff1a;操作系統進化史與開源革命 一、操作系統&#xff1a;數字世界的基石 1.1 什么是操作系統&#xff1f; 操作系統&#xff08;OS&#xff09;是計算機系統的核心管理者&#xff0c;承擔著三大核心使命&#xff1a; 硬件指揮官&#xff1a;直接管理C…

如何修改安全帽/反光衣檢測AI邊緣計算智能分析網關V4的IP地址?

TSINGSEE青犀推出的智能分析網關V4&#xff0c;是一款集成了BM1684芯片的高性能AI邊緣計算智能硬件。其內置的高性能8核ARM A53處理器&#xff0c;主頻可高達2.3GHz&#xff0c;INT8峰值算力更是達到了驚人的17.6Tops。此外&#xff0c;該硬件還預裝了近40種AI算法模型&#xf…

【全棧開發】----Mysql基本配置與使用

本篇是在已下載Mysql的情況下進行的&#xff0c;若還未下載或未創建Mysql服務&#xff0c;請轉到這篇: 2024 年 MySQL 8.0.40 安裝配置、Workbench漢化教程最簡易&#xff08;保姆級&#xff09;_mysql8.0.40下載安裝教程-CSDN博客 本文對于mysql的操作均使用控制臺sql原生代碼…

C++ primer plus 第四節 復合類型

本章內容包括: ? 創建和使用數組 ? 創建和使用 c-風格字符串 ? 創建和使用 string 類字符串 ? 使用方法getline( )和 get( )讀取字符串 ? 混合輸入字符串和數字 ? 創建和使用結構 ? 創建和使用共用休 ? 創建和使用枚舉 ? 創建和使用指針 ? 使用 new和delete 管理動態…

Java中的泛型類 --為集合的學習做準備

學習目標 ● 掌握在集合中正確使用泛型 ● 了解泛型類、泛型接口、泛型方法 ● 了解泛型上下限 ● 了解基本的使用場景 1.有關泛型 1.1泛型的概念 泛型&#xff08;Generics&#xff09;是Java中引入的參數化類型機制&#xff0c;允許在定義類、接口或方法時使用類型參數&a…