力扣hot100:相交鏈表與反轉鏈表詳細思路講解(160,206)

問題描述

核心思路:雙指針交替遍歷

算法思想: 使用兩個指針 papb 分別從鏈表A和鏈表B的頭節點出發,同步向后遍歷。當任一指針走到鏈表末尾時,將其重定位到另一鏈表的頭節點繼續遍歷。若兩鏈表相交,papb 最終會在相交節點相遇;若不相交,則最終會同時到達 null

數學原理: 設鏈表A獨立部分長度為 a,鏈表B獨立部分長度為 b,公共部分長度為 c

  • 指針?pa?的路徑:a + (b - c) + c = a + b
  • 指針?pb?的路徑:b + (a - c) + c = a + b?兩指針走過的總長度均為?a + b,因此必然在相交節點(或?null)相遇。

代碼實現

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA==null||headB==null){return null;}ListNode pa=headA;ListNode pb=headB;while(pa!=pb){if(pa==null){pa=headB;}else{pa=pa.next;}if(pb==null){pb=headA;}else{pb=pb.next;}}return pa;}

復雜度分析

  • 時間復雜度:O(m + n),其中 m 和 n 分別為鏈表長度。
  • 空間復雜度:O(1),僅使用兩個指針。

關鍵點

  1. 循環終止條件pa == pb?時退出循環(包括兩者均為?null?的情況)。
  2. 重定位時機:當指針走到當前鏈表末尾時,立即切換到另一鏈表的頭部。
  3. 不相交處理:兩指針最終同時為?null,返回?null?符合預期。
其他解法對比
方法二:計算長度差(同步遍歷)

思路

  1. 遍歷兩鏈表,分別計算長度?lenA?和?lenB
  2. 長鏈表指針先走?|lenA - lenB|?步。
  3. 兩指針同步遍歷,相遇點即為相交節點。

代碼

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {int lenA = getLength(headA), lenB = getLength(headB);ListNode pa = headA, pb = headB;// 長鏈表指針先走差值步if (lenA > lenB) {for (int i = 0; i < lenA - lenB; i++) pa = pa.nextB; i++) pa = pa.next;} else {for (int i = 0; i < lenB - lenA; i++) pb = pb.next;}// 同步遍歷直至相遇while (pa != pb) {pa = pa.next;pb = pb.next;}return pa;
}private int getLength(ListNode head) {int lenLength(ListNode head) {int len = 0;while (head != null) {len++;head = head.next;}return len;
}

復雜度

  • 時間復雜度:O(m + n)(需兩次遍歷)。
  • 空間復雜度:O(1)。

適用場景: 當鏈表長度差異較大時,此方法可能略快于雙指針交替法。

方法三:哈希集合(空間換時間)

思路: 1時間) 思路

  1. 遍歷鏈表A,將所有節點存入?HashSet
  2. 遍歷鏈表B,檢查節點是否在集合中,第一個存在的節點即為交點。

代碼

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {Set<ListNode> set = new HashSet<>();while (headA != null) {set.add(headA);headA = headA.next;}while (headB != null) {if (set.contains(headB)) return headB;headB = headB.next;}return null;
}

復雜度

  • 時間復雜度:O(m + n)。
  • 空間復雜度:O(m)(存儲鏈表A的節點)。

適用場景: 對空間復雜度不敏感時,代碼最簡潔直觀。

方法對比總結
方法時間復雜度空間復雜度特點
雙指針交替遍歷O(m + n)O(1)空間最優,代碼簡潔
計算長度差O(m + n)O(1)邏輯清晰,略多一次遍歷
哈希集合O(m + n)O(m)思路直接,但需額外空間

推薦:雙指針交替遍歷法在空間和代碼簡潔性上表現最佳,是面試中的理想解法。

問題描述

核心解法:迭代雙指針法

算法思想: 使用雙指針 new_headtemp 動態反轉鏈表:

  • new_head:指向已反轉部分的頭節點(初始為null)
  • temp:遍歷原鏈表的當前節點?每次迭代將當前節點從原鏈表斷開,插入到反轉鏈表的頭部,實現原地反轉。

代碼實現

public ListNode reverseList(ListNode head) {ListNode new_head = null;ListNode temp = head;while (temp != null) {ListNode next = temp.next;  // 保存后繼節點temp.next = new_head;      // 當前節點指向反轉鏈表頭部new_head = temp;           // 更新反轉鏈表頭temp = next;               // 移動到下一個節點}return new_head;
}

圖解過程

原始鏈表:1 → 2 → 3 → 4 → null
迭代過程:
第1輪:new_head=1→null, temp=2
第2輪:new_head=2→1→null, temp=3
第3輪:new_head=3→2→1→null, temp=4
第4輪:new_head=4→3→2→1→null, temp=null

復雜度分析

  • 時間復雜度:O(n),僅需一次遍歷
  • 空間復雜度:O(1),僅使用常量空間

優勢

  • 原地操作,不占用額外空間
  • 邏輯清晰,代碼簡潔
  • 適用于所有編程語言的鏈表實現
其他經典解法
方法二:遞歸法(分治思想)

算法思想

  1. 遞歸到鏈表尾部
  2. 回溯時反轉節點指向
  3. 返回新的頭節點
public ListNode reverseList(ListNode head) {if (head == null || head.next == null) {return head;}ListNode newHead = reverseList(head.next); // 遞歸到尾部head.next.next = head;    // 反轉指針方向head.next = null;         // 斷開原指針return newHead;
}

復雜度分析

  • 時間復雜度:O(n)
  • 空間復雜度:O(n)(遞歸棧空間)

適用場景

  • 鏈表長度適中(避免棧溢出)
  • 需要簡潔的代碼表達
  • 函數式編程環境
方法三:頭插法(使用虛擬節點)

算法思想

  1. 創建虛擬頭節點?dummy
  2. 遍歷原鏈表,將每個節點插入到?dummy?之后
  3. 返回?dummy.next
public ListNode reverseList(ListNode head) {ListNode dummy = new ListNode(-1);ListNode cur = head;while (cur != null) {ListNode next = cur.next;   // 保存后繼節點cur.next = dummy.next;       // 頭插操作dummy.next = cur;            // 更新頭節點cur = next;                  // 移動指針}return dummy.next;
}

復雜度分析

  • 時間復雜度:O(n)
  • 空間復雜度:O(1)

優勢

  • 統一處理頭節點特殊情況
  • 邏輯更易理解
  • 支持鏈表的其他變形操作
方法對比總結
方法時間復雜度空間復雜度特點
迭代雙指針O(n)O(1)空間最優,推薦首選
遞歸法O(n)O(n)代碼簡潔,但空間消耗大
頭插法(虛擬節點)O(n)O(1)邏輯清晰,易擴展

核心技巧

  1. 指針保存:在修改節點指針前,必須保存后繼節點引用
  2. 頭插操作:將節點插入鏈表頭部是反轉的關鍵
  3. 終止條件:注意處理空鏈表和單節點鏈表的邊界情況

延伸思考

  • 如何反轉部分鏈表(區間反轉)?
  • 如何K個一組反轉鏈表?
  • 如何判斷鏈表是否有環?(快慢指針技巧)

迭代雙指針法因其優異的時空復雜度,成為面試和工程實踐中的首選方案。掌握這三種經典解法,能夠靈活應對各種鏈表反轉問題。

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

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

相關文章

跨平臺游戲引擎 Axmol-2.8.1 發布

所有使用 axmol-2.8.0 的開發者都應更新至此版本 Axmol 2.8.1 版本是一個以錯誤修復和功能改進為主的次要 LTS 長期支持版本&#xff0c;發布時間: 2025 年 9 月 5 日 &#x1f64f;感謝所有對 axmol 項目的貢獻者&#xff0c;包括財務贊助者&#xff1a;scorewarrior、peter…

通過PXE的方式實現Ubuntu 24.04 自動安裝

PXE自動化安裝Ubuntu 24.04的配置文件之前都是通過PXE來自動化安裝Redhat系列的&#xff0c;例如&#xff1a;Rocky9、Rocky10、CentOS7、銀河麒麟 Kylin-V10、Kylin-V11、OpenEuler 24.03等。現在安裝Ubuntu系列的跟紅帽的不太一樣&#xff0c;所以在這里介紹下。創建三個文件…

AOSP Framework開發的一些超方便的快捷命令

在系統源碼中發現的一些命令和快捷方式。我們在編譯源碼之前執行的source build/envsetup.sh,通過cat build/envsetup.sh發現如下命令 - lunch: lunch <product_name>-<build_variant>Selects <product_name> as the product to build, and <build_…

【Protues仿真】基于AT89C52單片機的數碼管驅動事例

目錄 0案例視頻效果展示 1 AT89C52單片機驅動單個數碼管 1.1 數碼管基礎知識 1.1.1外觀與引腳 1.1.2 共陰(CC) vs 共陽(CA) 1.1.3段碼表(以數字1為例) 1.1.4驅動方式A. 直連IO(最簡單,占用IO多)一個段一根線,共陰或共陽公共端固定接GND/VCC。適合單個數碼管、…

01-Redis 發展簡史與核心定位解析:從誕生到三大產品矩陣

目錄引言一、Redis 的起源與發展&#xff1a;從定制工具到開源生態二、Redis 的核心定位&#xff1a;不止是緩存的多面手三、Redis 三大產品矩陣&#xff1a;按需選擇的完整解決方案3.1 Redis Open Source&#xff08;社區版&#xff09;&#xff1a;入門與輕量場景首選3.2 Red…

記錄jilu~

centos1、安裝最小版Linux 安裝必要工具yum -install -y epel-releaseyum -install -y net-toolsyum -install -y vim2、修改hostname hostnamectl net-hostname newhostname3、網絡配置文件&#xff0c;網關 &#xff0c; 使用ip &#xff0c;dns。。/etc/sysconfig/network-s…

【Linux基礎】fdisk命令詳解:從入門到精通的磁盤分區管理完全指南

目錄 前言 1 fdisk命令概述 1.1 什么是fdisk 1.2 fdisk的應用場景 1.3 fdisk與其他分區工具的比較 2 fdisk命令的安裝與基本語法 2.1 在不同Linux發行版中安裝fdisk 2.2 fdisk的基本語法 3 fdisk命令參數詳解 3.1 主要參數說明 3.2 交互式命令 4 fdisk操作流程詳解…

Flowable 工作流引擎

1、核心類 Flowable 引擎通過 ProcessEngine 作為總入口點&#xff0c;提供了多個核心服務接口&#xff0c;每個服務都負責特定的功能領域&#xff1a;服務名稱 (Service Name)主要功能 (Main Functionality)關鍵操作 (Key Operations)RepositoryService管理流程定義和部署&…

(RDFS)隨機深度特征選擇方法解釋:簡而言之,RDFS主要針對的是惡意的服務器,它建立在客戶端是誠實的前提下。

1. 隨機深度特征選擇是怎么實現的&#xff1f;隨機深度特征選擇 是一種在分布式機器學習&#xff08;特別是聯邦學習&#xff09;中用于保護客戶端數據隱私的技術。它的核心思想是&#xff1a;在每一輪訓練中&#xff0c;每個客戶端隨機選擇模型的一個子集&#xff08;即“深度…

C++20格式化字符串:std::format的使用與實踐

在C編程中&#xff0c;字符串格式化是一項常見的任務。在C20引入std::format之前&#xff0c;開發者通常依賴于一些傳統的解決方案&#xff0c;如printf系列函數、sstream&#xff0c;或者第三方庫如boost.format。然而&#xff0c;這些方法在代碼可讀性、類型安全性和靈活性方…

【漏洞復現】CVE-2025-8088|WinRAR 路徑穿越漏洞:從原理到藍屏攻擊全流程

【漏洞復現】CVE-2025-8088&#xff5c;WinRAR 路徑穿越漏洞&#xff1a;從原理到藍屏攻擊全流程 前言 WinRAR 作為 Windows 平臺最常用的壓縮管理工具之一&#xff0c;幾乎是每臺電腦的 “標配軟件”。但在 2025 年 8 月&#xff0c;一款影響范圍覆蓋 WinRAR 0 至 7.12 全版本…

uniapp中使用echarts并且支持pc端的拖動、拖拽和其他交互事件

npm install echarts -D ? // "echarts": "^5.3.2", [推薦版本] // "zrender": "^5.3.2" [如果報錯的話就安裝這個]<template><view class"container"><view id"myChart" class"chart"…

Qt中QProxyStyledrawControl函數4個參數的意義

Qt中QProxyStyle::drawControl函數4個參數的意義 我們來詳細解釋一下 Qt 中 QProxyStyle::drawControl 函數的四個參數。 這個函數是 Qt 樣式系統中的一個核心方法&#xff0c;用于繪制標準 UI 元素&#xff08;如按鈕、復選框、菜單欄等&#xff09;。當你繼承 QProxyStyle 并…

idf-esp32 PWM呼吸燈(LEDC頭文件)

相關宏和變量#define LED_PIN GPIO_NUM_3 #define LEDC_CHANNEL LEDC_CHANNEL_0 #define LEDC_TIMER LEDC_TIMER_0 #define LEDC_MODE LEDC_LOW_SPEED_MODE #define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 2^13 8192級亮度 #define LEDC_FREQUENCY 50…

PLC_博圖系列?基本指令”S_ODTS:分配保持型接通延時定時器參數并啟動“

PLC_博圖系列?基本指令”S_ODTS&#xff1a;分配保持型接通延時定時器參數并啟動“ 文章目錄PLC_博圖系列?基本指令”S_ODTS&#xff1a;分配保持型接通延時定時器參數并啟動“背景介紹S_ODTS&#xff1a; 分配保持型接通延時定時器參數并啟動說明參數脈沖時序圖示例關鍵字&a…

OneCode 可視化揭秘系列(三):AI MCP驅動的智能工作流邏輯編排

OneCode 可視化揭秘系列&#xff08;三&#xff09;&#xff1a;AI MCP驅動的智能工作流邏輯編排 引言 在前兩篇系列博文中&#xff0c;我們詳細探討了OneCode可視化動作的基礎配置與界面設計&#xff0c;以及組件交互與數據流管理。在本篇文章中&#xff0c;我們將深入剖析邏輯…

TypeORM、Sequelize、Hibernate 的優缺點對比:新手常見 SQL 與 ORM 踩坑總結

1. ORM 與關系型數據庫&#xff08;MySQL、PostgreSQL&#xff09; 的使用 SQL 語句編寫&#xff08;JOIN、GROUP BY、索引使用、事務控制&#xff09;與 ORM 映射&#xff08;如 Sequelize、TypeORM、Hibernate&#xff09;之間的差異會讓新手非常糾結&#xff1b;尤其是理解…

JavaScript 創建型設計模式詳解

1. 單例模式1.1. 使用場景在前端開發中&#xff0c;全局狀態管理、配置信息、數據庫連接等往往需要在應用中只存在一個實例&#xff0c;避免多次實例化帶來的數據不一致性。例如&#xff0c;在一個前端應用中&#xff0c;全局的 loading 狀態通常需要一個單例模式來確保其唯一性…

k8s除了主server服務器可正常使用kubectl命令,其他節點不能使用原因,以及如何在其他k8s節點正常使用kubectl命令??

kubectl 并不是“只能”在主節點&#xff08;Control Plane Node&#xff09;使用&#xff0c;而是因為它需要訪問 Kubernetes 的 kube-apiserver&#xff0c;而 kube-apiserver 通常只在主節點上運行并監聽內部網絡。簡單來說kubectl 需要連接 kube-apiserver&#xff01;&…

Custom SRP - Complex Maps

https://catlikecoding.com/unity/tutorials/custom-srp/complex-maps/1 創建材質球我們的材質已經支持光照,并且支持 Albedo 和 Emission 貼圖.創建材質球,并應用下面的電路板的圖分別作為 albedo emission設置材質球的金屬度為 1 , 光滑度為 0.952 Mask Map在 albedo 圖上的不…