偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Python 鏈表面試題精講:如何判斷鏈表是否有環(huán)?如何找出環(huán)的入口節(jié)點(diǎn)?

開(kāi)發(fā)
今天我們就來(lái)剖析一道經(jīng)典題目:如何判斷一個(gè)鏈表是否有環(huán)? 如果你掌握了這一技巧,那下一步你應(yīng)該深入學(xué)習(xí):如何找到環(huán)的入口節(jié)點(diǎn)?

在 Python 面試中,鏈表的基礎(chǔ)題型幾乎每次都出現(xiàn)。今天我們就來(lái)剖析一道經(jīng)典題目:如何判斷一個(gè)鏈表是否有環(huán)? 如果你掌握了這一技巧,那下一步你應(yīng)該深入學(xué)習(xí):如何找到環(huán)的入口節(jié)點(diǎn)?

問(wèn)題描述

給定一個(gè)單向鏈表的頭節(jié)點(diǎn) head,判斷鏈表中是否存在環(huán),如果存在,請(qǐng)返回環(huán)的起始節(jié)點(diǎn)。

解法一:判斷鏈表是否有環(huán)(快慢指針)

首先我們使用**快慢指針(Floyd 判圈算法)**來(lái)判斷鏈表是否有環(huán):

  • slow 每次走一步
  • fast 每次走兩步
  • 如果兩者在某個(gè)節(jié)點(diǎn)相遇,就說(shuō)明存在環(huán)
def has_cycle(head: ListNode) -> bool:
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True
    return False

解法二:找出環(huán)的入口(重點(diǎn))

當(dāng)快慢指針相遇之后,說(shuō)明鏈表中存在環(huán)。此時(shí)我們可以使用如下方法找出環(huán)的起點(diǎn)(入口):

步驟解析:

  • 讓其中一個(gè)指針(如 slow)回到鏈表頭 head;
  • 然后兩個(gè)指針都改為每次走一步;
  • 當(dāng)兩個(gè)指針再次相遇時(shí),就是環(huán)的入口。

原理解釋:

設(shè):

  • a 是頭節(jié)點(diǎn)到環(huán)入口的長(zhǎng)度;
  • b 是環(huán)入口到相遇點(diǎn)的長(zhǎng)度;
  • c 是環(huán)剩下的長(zhǎng)度(使得一圈為 b + c);

因?yàn)榭熘羔樧叩木嚯x是慢指針的兩倍:

2(a + b) = a + b + n(b + c)
推導(dǎo)得:a = c + (n - 1)(b + c)

說(shuō)明從頭節(jié)點(diǎn)走 a 步、從相遇點(diǎn)走 c 步,兩者會(huì)在環(huán)的入口節(jié)點(diǎn)重合。

完整代碼實(shí)現(xiàn)

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

def detect_cycle(head: ListNode) -> ListNode:
    """
    檢測(cè)鏈表中的環(huán),返回環(huán)的起始節(jié)點(diǎn)。如果無(wú)環(huán)返回 None。
    """
    slow = fast = head

    # 第一步:判斷是否有環(huán)
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            break
    else:
        return None  # 無(wú)環(huán)

    # 第二步:找環(huán)的入口
    slow = head
    while slow != fast:
        slow = slow.next
        fast = fast.next

    return slow  # 即為環(huán)的起始節(jié)點(diǎn)

測(cè)試樣例

# 創(chuàng)建一個(gè)環(huán)形鏈表:1 -> 2 -> 3 -> 4 -> 5 -> 3(回到節(jié)點(diǎn)3)

node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)
node5 = ListNode(5)
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node5.next = node3  # 形成環(huán),入口是node3

entry = detect_cycle(node1)
print(entry.val if entry else "無(wú)環(huán)")  # 輸出:3

小結(jié)與面試建議

面試點(diǎn)

內(nèi)容說(shuō)明

判斷有無(wú)環(huán)

快慢指針,相遇則有環(huán)

找到環(huán)入口

相遇后讓一指針回頭,兩個(gè)再同步前進(jìn)

時(shí)間復(fù)雜度

O(n)

空間復(fù)雜度

O(1)

這道題常被用于考察鏈表的操作能力、指針?biāo)季S和空間復(fù)雜度控制能力,理解 Floyd 判圈算法對(duì)于高級(jí)題型也是非常有幫助的。

責(zé)任編輯:趙寧寧 來(lái)源: Ssoul肥魚(yú)
相關(guān)推薦

2023-07-27 07:28:04

存儲(chǔ)鏈表HashSet

2022-04-07 08:37:05

鏈表技巧單鏈表

2021-05-31 18:47:04

環(huán)形鏈表哈希

2021-10-28 11:40:58

回文鏈表面試題數(shù)據(jù)結(jié)構(gòu)

2020-04-24 09:47:39

Python數(shù)據(jù)增長(zhǎng)率

2013-10-16 16:15:26

單鏈表

2025-02-11 07:40:27

2025-06-04 08:40:00

Go語(yǔ)言鏈表

2021-11-02 10:10:38

面試元素語(yǔ)言

2019-06-05 07:47:32

Nginx高并發(fā)多線程

2018-04-13 14:53:13

PythonMySQL爬蟲(chóng)

2021-01-26 05:21:29

無(wú)序鏈表HashSet

2014-09-19 11:17:48

面試題

2020-06-04 14:40:40

面試題Vue前端

2021-06-05 13:44:08

遞歸策略鏈表

2017-09-13 07:15:10

Python讀寫(xiě)文件函數(shù)

2023-05-19 08:21:40

MarginCSS

2015-09-07 09:15:54

Java面試題HashMap

2023-11-13 07:37:36

JS面試題線程

2011-03-24 13:27:37

SQL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)