數據結構(C語言篇):(六)單鏈表算法題(下)

目錄

前言

一、鏈表的回文結構

二、相交鏈表

三、環形鏈表?編輯

四、環形鏈表II

總結


前言

? ? ? ? 本篇博客將繼續介紹單鏈表相關的算法題,包括了鏈表的回文結構、相交鏈表、環形鏈表等。現在就讓我們正式開始吧!


一、鏈表的回文結構

????????題目鏈接:鏈表的回文結構_牛客題霸_牛客網

? ? ? ? 思路:創建數組(大小為900),遍歷鏈表將節點的值依次存儲在數組中,若數組為回文結構,則鏈表為回文結構。

? ? ? ? 解題核心邏輯如下:

  1. 將鏈表值復制到數組:遍歷鏈表,將所有節點的值存儲到數組中;

  2. 使用雙指針判斷回文:從數組兩端向中間遍歷,比較對應位置的值是否相等;

  3. 返回判斷結果:如果所有對應位置都相等,則是回文;否則不是。

? ? ? ? 完整代碼如下所示:

class PalindromeList {
public:bool chkPalindrome(ListNode* A) {// 創建固定大小的數組int arr[900] = {0};  // 假設鏈表長度不超過900// 遍歷鏈表,將值存儲到數組中ListNode* pcur = A;int i = 0;while(pcur) {arr[i++] = pcur->val;  // 存儲當前節點值,i后移pcur = pcur->next;     // 移動到下一個節點}// 使用雙指針判斷數組是否為回文int left = 0, right = i - 1;  // i是鏈表長度while(left < right) {if(arr[left] != arr[right]) {return false;  // 發現不對稱,不是回文}left++;right--;}return true;  // 所有對應位置都相等,是回文}
};

? ? ? ? 代碼的執行流程示例如下:假設鏈表為1 → 2 → 3 → 2 → 1 → NULL

步驟1:復制到數組
遍歷鏈表:arr[0]=1, arr[1]=2, arr[2]=3, arr[3]=2, arr[4]=1
i=5(鏈表長度)步驟2:雙指針判斷
left=0, right=4: 1==1 ?
left=1, right=3: 2==2 ?  
left=2, right=2: 循環結束
返回true

二、相交鏈表

? ? ? ? 題目鏈接:160. 相交鏈表 - 力扣(LeetCode)

? ? ? ? 思路:求兩個鏈表的長度,長鏈表先走長度差步,短鏈表開始同步遍歷,找相同的結點。

? ? ? ? 解題核心邏輯如下:

  1. 計算鏈表長度:分別遍歷兩個鏈表,計算它們的長度;

  2. 計算長度差:求出兩個鏈表長度的差值;

  3. 對齊起點:讓較長的鏈表先移動長度差的步數;

  4. 同時遍歷:兩個指針同時移動,直到找到相同節點或到達末尾。

? ? ? ? 完整代碼如下:

typedef struct ListNode ListNode;struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {// 求鏈表的長度ListNode* pa = headA;ListNode* pb = headB;int sizeA = 0, sizeB = 0;// 計算鏈表A的長度while(pa) {++sizeA;pa = pa->next;}// 計算鏈表B的長度while(pb) {++sizeB;pb = pb->next;}// 求長度差int gap = abs(sizeA - sizeB);  // 求絕對值// 定義長短鏈表ListNode* shortList = headA;ListNode* longList = headB;// 確定哪個鏈表更長if(sizeA > sizeB) {longList = headA;shortList = headB;}// 長鏈表先走gap步,對齊起點while(gap--) {longList = longList->next;}// shortList和longList現在在同一起跑線while(shortList) {  // 或者用while(longList)if(shortList == longList) {  // 找到相交節點return shortList;}shortList = shortList->next;longList = longList->next;}// 鏈表不相交return NULL;
}

? ? ? ? 執行流程的示例如下:

????????假設:
????????鏈表A:1 → 2 → 3 → 4 → 5 → NULL(長度5)
????????鏈表B:9 → 8 → 4 → 5 → NULL(長度4,從節點4開始相交)

步驟1:計算長度
sizeA = 5, sizeB = 4步驟2:計算長度差
gap = |5-4| = 1步驟3:確定長短鏈表
longList = headA, shortList = headB步驟4:長鏈表先走1步
longList從節點1移動到節點2步驟5:同時遍歷
shortList=9, longList=2 → 不相等
shortList=8, longList=3 → 不相等  
shortList=4, longList=4 → 相等,返回節點4

三、環形鏈表

? ? ? ? 題目鏈接:141. 環形鏈表 - 力扣(LeetCode)

? ? ? ? 思路:采用快慢指針方法,慢指針每次走一步,快指針每次走兩步,如果slow和fast指向了同一個結點,說明鏈表帶環。

? ? ? ? 對于這個思路,我們可以嘗試證明一下:

? ? ? ? 證明1:在環形鏈表中,慢指針每次走一步,快指針每次走兩步,最終是否一定會相遇?

? ? ? ? 如上圖所示,假設此時slow剛入環,此時slow和fast之間的距離最大,為N。slow和fast各自移動一次之后,距離縮小2 - 1 = 1,則此時距離為N - 1,那么在移動N次之后,最后fast和slow之間的距離將縮短為0,兩指針相遇。

? ? ? ? 證明2:在環形鏈表中,慢指針每次走一步,快指針每次走3、4、5、……步,快慢指針在環形鏈表中還會相遇嗎?答案是一定會相遇。

? ? ? ? 如上圖,假設此時slow剛入環,此時slow和fast之間的距離最大,為N。慢指針每次走一步,快指針每次走三步。每走一次,slow和fast之間距離就減小2,此時若N為偶數,那么最后兩者距離將減小為0,相遇;若N為奇數,那么距離會縮小為-1,此時就會套圈,兩者此時距離須以C-1來計算。若C-1為偶數,即C為奇數,那么一定會相遇;如果C-1為奇數,即C為偶數,則一定不會相遇。

? ? ? ? 下面我們再來推導一下快慢指針走的路程之間的關系:

? ? ? ? 如上圖,我們假設慢指針每次走1步,快指針一次走3步,那么就有:3 * 慢指針 = 快指針。我們假設慢指針所走路程為L,則快指針所走路程為:L + C - N + nC。根據以上等式,就有:3L = L + C - N + nC,整理得到:2L = (n+1)C - N。如下:

💡TIPS

????????雖然我們已經證明了快指針無論走多少步都可以滿足在帶環鏈表中相遇,但是在編寫代碼的時候會有額外的步驟引入,涉及到快慢指針的算法題中通常習慣使用慢指針走一步快指針走兩步的方式。

? ? ? ? 因此本題我們解題的核心邏輯如下:

???????1.? 初始化兩個指針

????????slow(慢指針):每次移動一步;

????????fast(快指針):每次移動兩步。

? ? ? ? 2.? 同時移動指針

????????????????慢指針每次移動1步,快指針每次移動2步;

????????????????如果鏈表有環,快慢指針最終會相遇;

????????????????如果鏈表無環,快指針會先到達NULL。

? ? ? ? 3.? 終止條件

????????????????快慢指針相遇 → 有環,返回true;

????????????????快指針到達NULL → 無環,返回false。

????????完整代碼如下:

typedef struct ListNode ListNode;bool hasCycle(struct ListNode *head) {// 創建快慢指針ListNode* slow = head;  // 慢指針,每次移動1步ListNode* fast = head;  // 快指針,每次移動2步// 循環條件:快指針和快指針的下一個節點都不為NULLwhile(fast && fast->next) {slow = slow->next;        // 慢指針移動1步fast = fast->next->next;  // 快指針移動2步if(slow == fast) {        // 如果相遇return true;          // 鏈表有環}}// 快指針到達NULL,鏈表不帶環return false;
}

? ? ? ? 下面提供兩個執行流程的示例:

? ? ? ? 1.? 有環鏈表:1 → 2 → 3 → 4 → 5 → 3(形成環)

初始:slow=1, fast=1
第1輪:slow=2, fast=3
第2輪:slow=3, fast=5 ?
第3輪:slow=4, fast=3
第4輪:slow=5, fast=5 → 相遇,返回true初始:slow=1, fast=1
第1輪:slow=2, fast=3
第2輪:slow=3, fast=5 ?
第3輪:slow=4, fast=3
第4輪:slow=5, fast=5 → 相遇,返回true

? ? ? ? 2.? 無環鏈表: 1→ 2 → 3 → 4 → 5 → NULL

初始:slow=1, fast=1
第1輪:slow=2, fast=3
第2輪:slow=3, fast=5
第3輪:slow=4, fast=NULL → 循環結束,返回false

四、環形鏈表II

? ? ? ? 題目鏈接:142. 環形鏈表 II - 力扣(LeetCode)

? ? ? ? 思路:快慢指針,在環里一定會相遇。相遇點到入環結點的距離 == 頭結點到入環結點的距離

💡結論

? ? ? ? 讓一個指針從鏈表起始位置開始遍歷鏈表,同時讓一個指針從判環時相遇點的位置開始繞環運行,兩個指針都是每次均走一步,最終肯定會在入口點的位置相遇。

? ? ? ? 下面我們先來證明一下以上結論:

? ? ? ? H為鏈表的起始點,E為環的入口點,M與判環時候相遇點。

? ? ? ? 假設:環的長度為R,H到E的距離為L,E到M的距離為X,則:M到E的距離為R - X。

? ? ? ? 在判環的時候,快慢指針相遇時所走的路徑長度如下:

  • fast:L + X + nR
  • slow:L + X?

? ? ? ? 需要注意的是:

? ? ? ? 1.? 當慢指針進入環時,快指針可能已經在環中繞了n圈了,n至少為1。因為當快指針先進環走到M的位置,最后又會在M的位置與慢指針相遇。

? ? ? ? 2.? 慢指針進入環之后,快指針肯定會在慢指針走一圈之內追上慢指針。因為當慢指針進環之后,快慢指針之間的距離最多就是環的長度,而兩個指針在移動的時候,每次它們的距離都縮減一步,因此在慢指針移動一圈之前,快指針肯定是可以追上慢指針的,而快指針的速度是慢指針的兩倍,因此有如下關系:

? ? ? ? 2 * (L + X) = L + X + nR;

? ? ? ? L + X = nR;

? ? ? ? L = nR - X;

? ? ? ? L = (n - 1)R + (R - X)

? ? ? ? (n = 1、2、3、4、……、n,n的大小取決于環的大小,環越小n越大)

? ? ? ? 在極端情況下,我們假設n = 1,此時有:L = R - X。

? ? ? ? 即:一個指針從鏈表起始位置運行,一個指針從相遇點位置繞環,每次都走一步,兩個指針最終會在入口點的位置相遇。

? ? ? ? 完整代碼如下:

typedef struct ListNode ListNode;struct ListNode *detectCycle(struct ListNode *head) {// 創建快慢指針ListNode* slow = head;  // 慢指針,每次移動1步ListNode* fast = head;  // 快指針,每次移動2步// 第一階段:判斷是否有環while(fast && fast->next) {slow = slow->next;        // 慢指針移動1步fast = fast->next->next;  // 快指針移動2步if(slow == fast) {        // 如果相遇,說明有環// 第二階段:尋找環入口// 數學原理:頭節點到入口的距離 = 相遇點到入口的距離ListNode* pcur = head;while(pcur != slow) {pcur = pcur->next;  // pcur從頭節點開始slow = slow->next;  // slow從相遇點開始}return pcur;  // 相遇點即為環入口}}// 快指針到達NULL,鏈表不帶環return NULL;
}

? ? ? ? 執行流程示例如下:1 → 2 → 3 → 4 → 5 → 3(形成環,入口在節點3)

步驟1:判斷有環
slow=1, fast=1
slow=2, fast=3
slow=3, fast=5 ?
slow=4, fast=3
slow=5, fast=5 → 相遇在節點5

步驟2:尋找環入口
pcur=head=1, slow=5
pcur=2, slow=3
pcur=3, slow=3 → 相遇在節點3(環入口)
返回節點3


總結

? ? ? ? 以上就是本期單鏈表算法題的全部內容啦~~~下期博客我將為大家帶來雙向鏈表的相關知識介紹,請大家多多關注、多多支持哦!

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

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

相關文章

【AI自動化】VSCode+Playwright+codegen+nodejs自動化腳本生成

VSCodePlaywrightnodejs&#xff0c;能完美實現UI自動化全流程腳本自動生成和回放&#xff0c;生成的腳本方便維護&#xff0c;回放執行快速&#xff1b; 概述 Playwright 是由Microsoft開發的一個開源的跨瀏覽器自動化測試庫&#xff0c;它支持Chromium、WebKit和Firefox瀏覽…

基于能量方法的納維-斯托克斯方程高階范數有界性理論推導-陳墨仙

寫在最前面&#xff0c;圈外人&#xff0c;沒有背書沒有教育郵箱&#xff0c;發不了預印本&#xff0c;我先發csdn。剛才首發沒復制完&#xff0c;抱歉&#xff0c;現在編輯下。基于能量方法的納維-斯托克斯方程高階范數有界性理論推導作者 陳墨仙郵件 2488888241qq.com摘要納維…

Labview邪修01:貪吃蛇

從博主很小的時候就在掌機上玩過這個貪吃蛇的小游戲&#xff0c;突然有一天心血來潮的想Labview是不是也可以編這個小游戲&#xff0c;回憶一下童年&#xff01;然后就又了下面的這個程序&#xff0c;執行結果如下圖所示。 基本功能&#xff1a; 1&#xff09;點擊開始按鈕&am…

將自己的jar包發布到maven中央倉庫(2025-08-29)

將自己的jar包發布到maven中央倉庫(2025-08-29) 一、注冊賬號 https://central.sonatype.com/ 二、新建命名空間 這里的命名空間需要填寫github的用戶名因為我的用戶名是daimao0,所以命名空間填io.github.daimao0 這里要求你建一個名為ubuxfc5q7r的公共項目&#xff0c;先創…

Spring CompositeCacheManager融合緩存

這是一個非常實用但容易被忽視的組件,它在特定的緩存場景下能提供極大的靈活性。 1. 核心概念:它是什么? ??CompositeCacheManager?? 是 Spring Framework 緩存抽象(spring-context模塊)的一部分。它的核心作用正如其名——??組合(Composite)??。 它本身并不…

無懈可擊的 TCP AIMD

不特指 TCP AIMD&#xff0c;而泛指控制范疇的所有 Additive Increase / Multiplicative Decrease 算法&#xff0c;繼 難以超越的 TCP AIMD 再敘。 “你永遠不能僅憑 BBR 的吞吐更高就說 BBR 比 CUBIC 更好” 這句話怎么總是沒人看&#xff0c;這句話是這一系列文章的前提論點…

數據集數量與神經網絡參數關系分析

1. 理論基礎 1.1 經驗法則與理論依據 神經網絡的參數量與所需數據集大小之間存在重要的關系&#xff0c;這直接影響模型的泛化能力和訓練效果。 經典經驗法則10倍法則&#xff1a;數據樣本數量應至少為模型參數量的10倍 公式&#xff1a;數據量 ≥ 10 參數量適用于大多數監督學…

項目經驗處理

訂單取消和支付成功并發問題 這是一個非常經典且重要的分布式系統問題。訂單取消和支付成功同時發生&#xff0c;本質上是一個資源競爭問題&#xff0c;核心在于如何保證兩個并發操作對訂單狀態的修改滿足業務的最終一致性&#xff08;即一個訂單最終只能有一種確定的狀態&…

rabbitmq學習筆記 ----- 多級消息延遲始終為 20s 問題排查

問題現象 在實現多級延遲消息功能時&#xff0c;發現每次消息延遲間隔始終為20s&#xff0c;無法按照預期依次使用20s→10s→5s的延遲時間。日志顯示每次處理時移除的延遲時間都是20000L。 問題代碼片段 1.生產者 Testvoid sendDelayMessage2() {List<Long> expireTimeLi…

軟件測試(三):測試流程及測試用例

1.測試流程1.需求分析進行測試之前先閱讀需求文檔&#xff0c;分析指出不合理或不明確的地方2.計劃編寫與測試用例測試用例用例即&#xff1a;用戶使用的案例測試用例&#xff1a;執行測試的文檔作用&#xff1a;用例格式&#xff1a;----------------------------------------…

Python:列表的進階技巧

列表&#xff08;list&#xff09;作為 Python 最常用的數據結構之一&#xff0c;不僅能存儲有序數據&#xff0c;還能在推導式、函數參數傳遞、數據處理等場景中發揮強大作用。下面介紹一些進階技巧與常見應用。一、去重與排序1、快速去重&#xff08;不保序&#xff09;nums …

【完整源碼+數據集+部署教程】硬幣分類與識別系統源碼和數據集:改進yolo11-SWC

背景意義 隨著經濟的發展和數字支付的普及&#xff0c;傳統硬幣的使用逐漸減少&#xff0c;但在某些地區和特定場合&#xff0c;硬幣仍然是重要的支付手段。因此&#xff0c;硬幣的分類與識別在自動化支付、智能零售和物聯網等領域具有重要的應用價值。尤其是在銀行、商超和自助…

萊特萊德:以“第四代極限分離技術”,賦能生物發酵產業升級

萊特萊德&#xff1a;以“第四代極限分離技術”&#xff0c;賦能生物發酵產業升級Empowering Upgrades in the Bio-Fermentation Industry with "Fourth-Generation Extreme Separation Technology生物發酵行業正經歷從 “規模擴張” 向 “質效提升” 的關鍵轉型&#xff…

外賣大戰之后,再看美團的護城河

美團&#xff08;03690.HK&#xff09;于近日發布了2025年Q2財報&#xff0c;市場無疑將更多目光投向了其備受關注的外賣業務上。毫無懸念&#xff0c;受外賣競爭和加大投入的成本影響&#xff0c;美團在外賣業務上的財務數據受到明顯壓力&#xff0c;利潤大幅下跌&#xff0c;…

R包fastWGCNA - 快速執行WGCNA分析和下游分析可視化

最新版本: 1.0.0可以對著視頻教程學習和使用&#xff1a;然而還沒錄呢, 關注B站等我更新R包介紹 開發背景 WGCNA是轉錄組或芯片表達譜數據常用得分析, 可用來鑒定跟分組或表型相關得模塊基因和核心基因但其步驟非常之多, 每次運行起來很是費勁, 但需要修改的參數并不多所以完全…

GitHub 熱榜項目 - 日榜(2025-08-29)

GitHub 熱榜項目 - 日榜(2025-08-29) 生成于&#xff1a;2025-08-29 統計摘要 共發現熱門項目&#xff1a;11 個 榜單類型&#xff1a;日榜 本期熱點趨勢總結 本期GitHub熱榜展現出三大技術趨勢&#xff1a;1&#xff09;AI應用持續深化&#xff0c;ChatGPT等大模型系統提示…

【深度學習實戰(58)】bash方式啟動模型訓練

export \PATHPYTHONPATH/workspace/mmlab/mmdetection/:/workspace/mmlab/mmsegmentation/:/workspace/mmlab/mmdeploy/:${env:PYTHONPATH} \CUDA_VISIBLE_DEVICES0 \DATA_ROOT_1/mnt/data/…/ \DATA_ROOT_2/mnt/data/…/ \DATA_ROOT_MASK/…/ \PATH_COMMON_PACKAGES_SO…sonoh…

【物聯網】關于 GATT (Generic Attribute Profile)基本概念與三種操作(Read / Write / Notify)的理解

“BLE 讀寫”在這里具體指什么&#xff1f; 在你的系統里&#xff0c;樹莓派是 BLE Central&#xff0c;Arduino 是 BLE Peripheral。 Central 和 Peripheral 通過 **GATT 特征&#xff08;Characteristic&#xff09;**交互&#xff1a;讀&#xff08;Read&#xff09;&#x…

JavaSE丨集合框架入門(二):從 0 掌握 Set 集合

這節我們接著學習 Set 集合。一、Set 集合1.1 Set 概述java.util.Set 接口繼承了 Collection 接口&#xff0c;是常用的一種集合類型。 相對于之前學習的List集合&#xff0c;Set集合特點如下&#xff1a;除了具有 Collection 集合的特點&#xff0c;還具有自己的一些特點&…

金屬結構疲勞壽命預測與健康監測技術—— 融合能量法、紅外熱像技術與深度學習的前沿實踐

理論基礎與核心方法 疲勞經典理論及其瓶頸 1.1.疲勞失效的微觀與宏觀機理&#xff1a; 裂紋萌生、擴展與斷裂的物理過程。 1.2.傳統方法的回顧與評析。 1.3.引出核心問題&#xff1a;是否存在一個更具物理意義、能統一描述疲勞全過程&#xff08;萌生與擴展&#xff09;且試驗量…