Python面試問題指南:如何編碼鏈表

image

什么是鏈表?


鏈表是一種數(shù)據(jù)結(jié)構(gòu)才避,由許多稱為“節(jié)點(diǎn)”的迷你數(shù)據(jù)結(jié)構(gòu)組成橱夭。節(jié)點(diǎn)鏈接在一起形成一個(gè)列表。

整個(gè)鏈表桑逝,由3個(gè)節(jié)點(diǎn)鏈接在一起組成棘劣。

每個(gè)節(jié)點(diǎn)包含2個(gè)屬性
  1. 它的價(jià)值。這可以是任何東西:整數(shù)楞遏,字符茬暇,字符串,對(duì)象等寡喝。

  2. 指向序列中下一個(gè)節(jié)點(diǎn)的指針糙俗。

一些定義

頭節(jié)點(diǎn):頭節(jié)點(diǎn)只是鏈表中的第一個(gè)節(jié)點(diǎn)。從上面的例子可以看出预鬓,包含'5'的節(jié)點(diǎn)是第一個(gè)節(jié)點(diǎn)巧骚,因此是頭部。

'尾節(jié)點(diǎn):尾節(jié)點(diǎn)是序列中的最后一個(gè)節(jié)點(diǎn)。由于它是最后一個(gè)節(jié)點(diǎn)网缝,因此它指向null,因?yàn)樾蛄兄袥]有下一個(gè)節(jié)點(diǎn)蟋定。在上面的示例中粉臊,包含“3”的節(jié)點(diǎn)將是尾節(jié)點(diǎn)。

單身聯(lián)系與雙重聯(lián)系


在鏈接列表方面驶兜,有兩種主要類型扼仲。

那些“單獨(dú)”聯(lián)系的,以及那些“雙重”聯(lián)系的抄淑。

單獨(dú)鏈接意味著每個(gè)節(jié)點(diǎn)僅指向最多1個(gè)其他節(jié)點(diǎn)屠凶,即其前面的節(jié)點(diǎn)。這在上面的例子中展示肆资。

單鏈表的一個(gè)例子

雙重鏈接意味著每個(gè)節(jié)點(diǎn)可以指向其他2個(gè)節(jié)點(diǎn)矗愧,前面的節(jié)點(diǎn)和它后面的節(jié)點(diǎn)。正如我們從下面的例子中可以看到的那樣郑原,由于頭節(jié)點(diǎn)之前沒有節(jié)點(diǎn)(即5)唉韭,因此其中一個(gè)指針指向null。

雙向鏈表的一個(gè)例子

代碼是如何工作的呢犯犁?


編碼鏈接列表可能是4行問題或400行問題属愤。這取決于你想要如何接近它。

在最簡(jiǎn)單的層面上酸役,就像我們討論的那樣住诸,鏈表只是一堆連接的節(jié)點(diǎn)。

因此涣澡,我們真正需要?jiǎng)?chuàng)建此結(jié)構(gòu)的只是一個(gè)節(jié)點(diǎn)對(duì)象贱呐。

class linkedListNode:
    def __init__(self, value, nextNode=None):
        self.value = value
        self.nextNode = nextNode

在這里我們可以看到我們只是創(chuàng)建了一個(gè)具有value和nextNode屬性的類。

要?jiǎng)?chuàng)建節(jié)點(diǎn)暑塑,我們只需傳入一個(gè)值吼句。

node1 = linkedListNode("3") # "3"
node2 = linkedListNode("7") # "7"
node3 = linkedListNode("10") # "10"

在這里,我們創(chuàng)建了3個(gè)單獨(dú)的節(jié)點(diǎn)事格。

下一步就是將它們連接在一起惕艳。

node1.nextNode = node2 
node2.nextNode = node3 

上面的第一行使node1指向node2:

“3”→“7”

上面的第二行使node2指向node3:

“7”→” 10"

總之,我們留下了一個(gè)鏈接列表驹愚,如下所示:

“3”→” 7" →” 10" →null

注意:“10”指向null远搪,因?yàn)闆]有為node3分配nextNode,并且默認(rèn)的nextNode為Null逢捺。

就像我之前提到的谁鳍,有很多不同的方法可以做到這一點(diǎn)。這只是最簡(jiǎn)單的。

遍歷鏈接列表


如果您正在進(jìn)行編程訪談倘潜,并且您會(huì)收到鏈接列表問題绷柒,那么您將無法獲得所有節(jié)點(diǎn)。

所有你得到的是頭節(jié)點(diǎn)涮因。

這里傳遞的所有內(nèi)容都是頭節(jié)點(diǎn)

從該頭節(jié)點(diǎn)废睦,您必須獲得列表的其余部分。

首先讓我們了解如何從Python中的節(jié)點(diǎn)獲取值和nextNode养泡。

假設(shè)我們有一個(gè)名為'node'的節(jié)點(diǎn)嗜湃。

獲取節(jié)點(diǎn)的值:

node.value

獲取節(jié)點(diǎn)的nextNode:

node.nextNode

Traversal


我們要做的第一件事就是創(chuàng)建一個(gè)名為“currentNode”的變量來跟蹤我們所處的節(jié)點(diǎn)。我們首先想要將它分配給我們的頭節(jié)點(diǎn)澜掩。

currentNode = head

現(xiàn)在我們要做的就是檢查當(dāng)前節(jié)點(diǎn)是否為Null购披。如果不是,我們將'currentNode'等于'currentNode'的'nextNode'肩榕。

currentNode = node1
while currentNode is not None:
    currentNode = currentNode.nextNode

假設(shè)我們有以下鏈接列表:“3”→“7”→“10”刚陡。

我們的頭和第一個(gè)'currentNode'是“3”。

當(dāng)我們這樣做

currentNode = currentNode.nextNode

我們將'currentNode'重新分配給當(dāng)前節(jié)點(diǎn)的鄰居株汉,在這種情況下是“7”橘荠。

這將繼續(xù),直到currentNode指向None郎逃,在這種情況下循環(huán)停止哥童。

這是在Python中遍歷鏈表的基本方法。

鏈接到Github上的代碼褒翰。

插入元素


將元素插入鏈接列表時(shí)贮懈,除非另有說明,否則將其插入后面优训。

我們使用以下示例:

“3”→” 7" →” 10" →空

假設(shè)我們要插入一個(gè)“4”朵你。

我們只需找到尾節(jié)點(diǎn),在本例中為“10”揣非,并將其nextNode設(shè)置為“4”節(jié)點(diǎn)抡医。

“3”→” 7" →” 10" →‘4’→null

node4 = linkedListNode("4")
node3.nextNode = node4

假設(shè)我們?cè)谝粋€(gè)訪談中,我們只有head節(jié)點(diǎn)早敬。我們只需遍歷LinkedList即可找到尾部忌傻。一旦我們得到尾部,我們只需將其nextNode設(shè)置為我們創(chuàng)建的新節(jié)點(diǎn)搞监。

def insertNode(head, valuetoInsert):
    currentNode = head
    while currentNode is not None:
        if currentNode.nextNode is None:
            currentNode.nextNode = linkedListNode(valuetoInsert)
            return head
        currentNode = currentNode.nextNode

刪除元素


刪除可能會(huì)有點(diǎn)棘手水孩。

我們來看同樣的例子。

“3”→” 7" →” 10" →null

如果我們想要?jiǎng)h除“7”琐驴,我們需要做的就是將“3”指向“10”俘种,以便永遠(yuǎn)不會(huì)引用“7”秤标。

“3”→” 10" →null

要做到這一點(diǎn),我們必須遍歷列表宙刘,同時(shí)不僅要跟蹤currentNode苍姜,還要跟蹤previousNode。

我們還必須考慮頭節(jié)點(diǎn)是我們想要?jiǎng)h除的節(jié)點(diǎn)悬包。

在下面的代碼中怖现,我們只刪除要?jiǎng)h除的值的第一個(gè)實(shí)例。

請(qǐng)注意玉罐,有很多方法可以實(shí)現(xiàn)這一點(diǎn),下面的解決方案可能不是您生活中最清晰的代碼潘拨。然而吊输,在采訪的熱度中,面試官可能不會(huì)期望教科書完美的代碼铁追。

def deleteNode(head, valueToDelete):
    currentNode = head
    previousNode = None
    while currentNode is not None:
        if currentNode.value == valueToDelete:
            if previousNode is None: 
                newHead = currentNode.nextNode
                currentNode.nextNode = None
                return newHead # Deleted the head
            previousNode.nextNode = currentNode.nextNode
            return head
        previousNode = currentNode
        currentNode = currentNode.nextNode
    return head # Value to delete was not found.

在上面的代碼中季蚂,一旦我們找到要?jiǎng)h除的節(jié)點(diǎn),我們將前一節(jié)點(diǎn)的“nextNode”設(shè)置為已刪除節(jié)點(diǎn)的“nextNode”琅束,以將其完全從列表中刪除扭屁。

大O時(shí)間復(fù)雜性分析


注意這些是上述節(jié)點(diǎn)結(jié)構(gòu)的時(shí)間復(fù)雜性,最有可能出現(xiàn)在訪談中涩禀。在實(shí)際情況中料滥,您可以將屬性存儲(chǔ)在LinkedList類中以降低這些復(fù)雜性。

'n'=鏈接列表中的元素?cái)?shù)量艾船。

插入到鏈接列表的后面 -我們遍歷所有n個(gè)元素以找到尾部并插入我們的新節(jié)點(diǎn)葵腹。O(n)

插入鏈接列表的前面 -?我們只需創(chuàng)建新節(jié)點(diǎn)并將其nextNode設(shè)置為head。無需遍歷列表屿岂。O(1)

遍歷 - ?我們遍歷所有n個(gè)元素践宴。O(n)

刪除 -?最糟糕的情況是,我們刪除的節(jié)點(diǎn)是最后一個(gè)節(jié)點(diǎn)爷怀,導(dǎo)致我們遍歷整個(gè)列表阻肩。O(n)

現(xiàn)在您已經(jīng)掌握了處理鏈表面試問題所需的基本知識(shí)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市运授,隨后出現(xiàn)的幾起案子烤惊,更是在濱河造成了極大的恐慌,老刑警劉巖吁朦,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撕氧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡喇完,警方通過查閱死者的電腦和手機(jī)伦泥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門剥啤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人不脯,你說我怎么就攤上這事府怯。” “怎么了防楷?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵牺丙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我复局,道長(zhǎng)冲簿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任亿昏,我火速辦了婚禮峦剔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘角钩。我一直安慰自己吝沫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布递礼。 她就那樣靜靜地躺著惨险,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脊髓。 梳的紋絲不亂的頭發(fā)上辫愉,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音将硝,去河邊找鬼一屋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛袋哼,可吹牛的內(nèi)容都是我干的冀墨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼涛贯,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼诽嘉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起弟翘,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤虫腋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后稀余,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悦冀,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年睛琳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盒蟆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踏烙。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖历等,靈堂內(nèi)的尸體忽然破棺而出讨惩,到底是詐尸還是另有隱情,我是刑警寧澤寒屯,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布荐捻,位于F島的核電站,受9級(jí)特大地震影響寡夹,放射性物質(zhì)發(fā)生泄漏处面。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一菩掏、第九天 我趴在偏房一處隱蔽的房頂上張望魂角。 院中可真熱鬧,春花似錦患蹂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至醉顽,卻和暖如春沼溜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背游添。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工系草, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唆涝。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓找都,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親廊酣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子能耻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容