鏈表題解——回文鏈表【LeetCode】

一、算法邏輯(通順講解每一步思路)

我們從 isPalindrome 這個主函數入手:

步驟 1:找到鏈表的中間節點 middleNode

  • 使用 快慢指針法(slow 和 fast)

  • 快指針一次走兩步,慢指針一次走一步。

  • 當快指針走到鏈表末尾時,慢指針剛好到達鏈表中點。

  • 目的:將鏈表劃分成前后兩部分。

步驟 2:反轉后半部分鏈表 reverseList

  • 從中點開始,就地反轉鏈表

  • 通過不斷修改 next 指針,實現鏈表的反轉。

  • 最終得到后半段鏈表的頭指針 head2

步驟 3:比較前半部分和反轉后的后半部分是否相等

  • 現在前半部分從 head 開始,后半部分從 head2 開始。

  • 每次比較兩個節點的值是否相等。

  • 若有一對值不同,說明不是回文,立即返回 False

  • 若后半段全部匹配完了,說明是回文鏈表,返回 True


二、核心點

  1. 快慢指針找中點 是核心技巧之一,它在 O(n) 時間內找出鏈表中點,無需額外空間。

  2. 就地反轉鏈表 則是另一個關鍵,它允許我們不借助棧或數組完成后半段反轉,依然保持 O(1) 空間復雜度。

  3. 最后通過同時遍歷前半部分與后半部分,實現了線性時間的比較。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = nextclass Solution:# 876. 鏈表的中間結點def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:slow = fast = headwhile fast and fast.next:slow = slow.nextfast = fast.next.nextreturn slow# 206. 反轉鏈表def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:pre, cur = None, headwhile cur:nxt = cur.nextcur.next = prepre = curcur = nxtreturn predef isPalindrome(self, head: Optional[ListNode]) -> bool:mid = self.middleNode(head)head2 = self.reverseList(mid)while head2:if head.val != head2.val:  # 不是回文鏈表return Falsehead = head.nexthead2 = head2.nextreturn True

三、時間復雜度分析

設鏈表長度為 n

  • middleNode(head):遍歷一次鏈表的一半,O(n)

  • reverseList(mid):最多遍歷一半鏈表,O(n)

  • 遍歷比較兩個鏈表:最多也是 O(n)

總時間復雜度:O(n)


四、空間復雜度分析

  • 所有操作都是原地進行的,沒有使用額外的數據結構(如棧或數組)

  • 使用的變量為常數個指針

總空間復雜度:O(1)(常數空間)


? 總結一句話

該算法巧妙地結合了快慢指針、鏈表反轉和雙指針比較,在線性時間和常數空間下高效判斷鏈表是否為回文。核心在于利用快慢指針找到中點 + 原地反轉鏈表來規避額外空間使用。

我的疑問與解答:

這段代碼中為什么不能使用直接 反轉鏈表然后判斷是否原鏈表和反轉后的相同,這樣的判斷方式不可行嗎

?問題本質:

你提到的思路是:

“直接把整個鏈表反轉一遍,然后和原鏈表一一比較是否相等”。

聽起來直觀、簡單,但在鏈表這種數據結構下,這么做實際上是不可行的,除非我們付出額外代價。我們分析一下為啥。


🚫 為什么不能直接這么做?

? 原鏈表一旦反轉,結構就被破壞了

鏈表是單向的引用結構,一旦你改變 next 指針,原來的鏈表結構就消失了。例如:

原鏈表: A -> B -> C 反轉后: C -> B -> A

反轉后,你再也無法回到原鏈表,兩個鏈表共享節點,無法保留兩個版本


? 比較“原鏈表”和“反轉鏈表”時無法共存

不像數組可以直接復制出一個副本(空間 O(n)),鏈表如果你想保留“原鏈表”+“反轉鏈表”,只能:

  • 額外復制整個鏈表結構(用 O(n) 空間);

  • 或者做深拷貝 + 比較。

那樣時間和空間復雜度都增加了,失去了當前算法 O(1) 空間的優勢。


? 現在這段代碼做了什么優化?

? 它沒有修改前半部分鏈表

只從鏈表中點開始反轉,因此:

  • 前半部分結構保留了;

  • 后半部分結構反轉后,可以直接比較;

  • 全過程不需要額外空間。


🔁 可選做法(進階)

? 如果你真的想“保留鏈表結構不變”,可以在比較完后再反轉一次恢復結構。

這是一些面試官會追問的點:“你破壞了鏈表結構,要不要恢復?”

你可以在最后加一句:

self.reverseList(head2) # 恢復后半部分結構(非必須,取決于題意)

? 結論總結:

方式是否可行空間復雜度是否破壞鏈表結構是否高效
整體反轉 + 比較原鏈表? 不可行O(n) or 破壞原鏈表會破壞結構
復制一份 + 反轉副本 + 比較? 可行O(n)不破壞
當前解法(快慢指針+反轉后半段)? 優秀解O(1)前半結構保留是 ??

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

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

相關文章

allegro 銅皮的直角邊怎么快速變成多邊形?

像這種: 變成這種: 解決方案: shape edit boundary 點擊鋪銅邊緣就能裁剪

從廚房到代碼臺:用做菜思維理解iOS開發 - Swift入門篇②

從廚房到代碼臺:用做菜思維理解iOS開發 - Swift入門篇② 本章重點? 理解App開發的整體流程熟悉Xcode主界面結構與常用分區跟著步驟動手創建第一個App項目,認識模擬器掌握"打掃廚房"高頻快捷鍵,解決常見疑難雜癥 1、目標 像一個專…

EloqCloud for KV 初體驗:兼容redis的云原生KV數據庫

最近在做一些AI應用的時候,我在想嘗試利用redis的能力緩存一些信息,這使我想去找一個免費的redis來進行使用,在調研的過程中我發現了一款產品EloqCloud for KV可以提供類似的能力,于是嘗試使用了一下,本文記錄了這次體…

企業級路由器技術全解析:從基礎原理到實戰開發

簡介 在當今數字化時代,路由器作為網絡的核心設備,其技術深度與應用廣度直接影響著企業網絡的性能與安全性。本文將全面解析路由器的基礎原理、工作機制以及企業級開發技術,從網絡層尋址到路由協議算法,從安全配置到QoS實現,再到多廠商API開發實戰,旨在幫助網絡工程師和…

day041-web集群架構搭建

文章目錄 0. 老男孩思想-高薪四板斧1. web集群架構圖2. 搭建異地備份服務2.1 服務端-阿里云服務器2.1.1 查看rsync軟件包2.1.2 添加rsync配置文件2.1.3 添加虛擬用戶2.1.4 創建校驗用戶密碼文件2.1.5 創建備份目錄2.1.6 啟動服務2.1.7 開放安全組端口2.1.8 發送檢查郵件 2.2 客…

day44-Django RestFramework(drf)下

1.5 Django RestFramework(下) drf 內置了很多便捷的功能,在接下來的課程中會給大家依次講解下面的內容: 快速上手請求的封裝版本管理認證權限限流序列化視圖條件搜索分頁路由解析器10. 分頁 在查看數據列表的API中,如果 數據量 比較大,肯定不能把所有的數據都展示給用…

機器學習基礎 線性回歸與 Softmax 回歸

機器學習基礎 線性回歸與 Softmax 回歸 文章目錄 機器學習基礎 線性回歸與 Softmax 回歸1. 最小二乘法1.1 數據集定義1.2 最小二乘的矩陣推導1.3 最小二乘的幾何解釋1.4 概率視角下的最小二乘估計 2. 正則化2.1 L1 范數與 L2 范數2.2 正則化的作用2.3 Lasso 回歸的求解2.3.1 L-…

6.27_JAVA_面試(被抽到了)

1.MYSQL支持的存儲引擎有哪些, 有什么區別 ? In-no-DB(默認):支持事務安全(數據庫運行時,能保證數據的一致性、完整性),支持表行鎖,支持物理和邏輯外鍵。占用磁盤空間大。 MEMORY&…

YOLOv13震撼發布:超圖增強引領目標檢測新紀元

YOLOV13最近發布了,速速來看。 論文標題:YOLOv13:融合超圖增強的自適應視覺感知的實時目標檢測 論文鏈接:https://arxiv.org/pdf/2506.17733 代碼鏈接:https://github.com/iMoonLab/yolov13 話不多說,直…

Docker錯誤問題解決方法

1. Error response from daemon: Get “https://registry-1.docker.io/v2/”: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) https://zhuanlan.zhihu.com/p/24228872523 2. no configuration file provided: …

大模型在惡性心律失常預測及治療方案制定中的應用研究

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與方法 1.3 研究創新點 二、大模型技術概述 2.1 大模型基本原理 2.2 常見大模型類型及特點 2.3 大模型在醫療領域的應用現狀 三、心律失常的術前預測與準備 3.1 術前心律失常預測的重要性 3.2 大模型在術前預測中的應…

【視頻芯片選型】

一、邊緣 AI 芯片選型邏輯與未來趨勢 (一)嘉楠 K230、全志 V853、瑞芯微 RK3588 對比選型 核心場景適配 嘉楠 K230: 適合低功耗邊緣 AI場景,如智能家居中控(支持語音 視覺雙模態交互)、電池供電設備&#…

JavaScript---DOM篇

1. DOM 概念 文檔對象模型:將 HTML 文檔映射為樹形結構,JS 可通過 DOM 操作頁面。 2. 獲取元素 document.getElementById(id) document.querySelector(CSS選擇器) document.querySelectorAll() 獲取多個 3. 操作元素 屬性操作: element.getAt…

第三次課:實驗室安全用電

觸電的危害 觸電的方式 安全用電與預防措施 觸電急救 時間就是生命 安全自省 安全用電常識補充

NV064NV065美光固態閃存NV067NV076

美光NV系列固態閃存技術深度解析與應用指南 技術架構革新:垂直堆疊與浮柵技術的突破 美光NV系列固態閃存的核心競爭力在于其232層NAND閃存技術,通過垂直堆疊工藝將存儲單元層層疊加,如同在指甲蓋面積內構建超過200層“數據樓宇”&#xff0…

設計模式精講 Day 18:備忘錄模式(Memento Pattern)

【設計模式精講 Day 18】備忘錄模式(Memento Pattern) 文章內容 開篇 在“設計模式精講”系列的第18天,我們來探討備忘錄模式(Memento Pattern)。這是一種行為型設計模式,其核心思想是在不破壞封裝性的前…

SpringCloud系列(35)--使用HystrixDashboard進行服務監控

前言:在上一節中我們使用了Hystrix進行服務熔斷處理,至此關于Hystrix的使用到此為止,本節內容關注的是如何使用HystrixDashboard對調用進行監控。 1、HystrixDashboard概述 Hystrix提供的準實時的調用監控(HystrixDashboard),Hys…

爬蟲簡單實操2——以貼吧為例爬取“某吧”前10頁的網頁代碼

需求是將貼吧的【某個吧】里面【n頁】的網頁代碼爬取下來,保存至本地 首先我們要思考這個貼吧爬蟲的框架,要有方法可以構造url列表(就可以一次獲取多個url),能請求獲取相應,能把html保存到本地。 import …

webpack5 css-loader 配置項中的modules

在 Webpack 的 css-loader 中,modules 選項是一個核心配置,它直接關系到 CSS 的模塊化處理方式。下面從概念、原理、使用場景和實踐技巧四個方面詳細解析: 概念解析:CSS Modules 是什么? CSS Modules 是一種讓 CSS 類…

springboot+Vue駕校管理系統

概述 基于springbootVue開發的駕校管理系統。該系統采用主流技術棧開發,功能完善,既包含用戶端便捷的操作界面,又具備強大的后臺管理功能。 主要內容 一、用戶端功能模塊 ??核心功能導航??: 首頁展示駕校推薦信息及最新動態…