0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

編程面試最常見的14種模式

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:陳年麗 ? 2019-08-01 11:24 ? 次閱讀

在面試程序員崗位時,我們往往需要經(jīng)歷一個編程面試過程,雇主會借此考驗面試者的技術(shù)實力。然而,這些技術(shù)問題有時候卻和我們的實際工作并無太大關(guān)系,也由此可能給我們的編程面試準(zhǔn)備階段帶來很大的壓力。曾在 Facebook 和微軟工作過的 Educative.io 創(chuàng)始人 Fahim ul Haq 近日發(fā)文總結(jié)了編程面試所遇到的問題的 14 種最常見的模式,也許能幫你看清各種編程面試問題「背后的真相」。機器之心也在文末補充了我們曾經(jīng)發(fā)布過的另外幾篇有關(guān)面試的文章,相信能給即將進入職場的程序員帶來幫助。

對很多開發(fā)者來說,編程工作的面試準(zhǔn)備很容易讓人焦慮。面試要涉及的東西實在太多,其中很多還往往與開發(fā)者的日常工作無關(guān),只會額外增添壓力。

這種現(xiàn)狀導(dǎo)致了一個后果:現(xiàn)在的開發(fā)者往往需要花費數(shù)周時間在 LeetCode 等網(wǎng)站上了解綜合數(shù)百個問題。與我談過的開發(fā)者在面試前的一個常見焦慮問題是:我是否已經(jīng)解決過足夠多的實際問題?我本可以做到更多嗎?

這就是我想要幫助開發(fā)者了解每個問題背后的底層模式的原因——這樣他們就不必擔(dān)憂解決數(shù)百個問題以及被 LeetCode 整得疲憊不堪了。如果你理解面試的通用模式,你就可以將其用作模板,從而解決各種層級的稍有不同的問題。

這里我將列出最常見的 14 種模式,它們可被用于解決任何編程面試問題。另外我還會說明如何識別每種模式,并會為每種模式提供一些問題示例。

下面的模式說明假設(shè)你已經(jīng)知悉了數(shù)據(jù)結(jié)構(gòu)。

我們今天將說明以下 14 種模式:

1.滑動窗口2.二指針或迭代器3.快速和慢速指針或迭代器4.合并區(qū)間5.循環(huán)排序6.原地反轉(zhuǎn)鏈表7.樹的寬度優(yōu)先搜索(Tree BFS)8.樹的深度優(yōu)先搜索(Tree DFS)9.Two Heaps10.子集11.經(jīng)過修改的二叉搜索12. 前 K 個元素13. K 路合并14.拓撲排序

我們開始吧!

1.滑動窗口

滑動窗口模式是用于在給定數(shù)組或鏈表的特定窗口大小上執(zhí)行所需的操作,比如尋找包含所有 1 的最長子數(shù)組。從第一個元素開始滑動窗口并逐個元素地向右滑,并根據(jù)你所求解的問題調(diào)整窗口的長度。在某些情況下窗口大小會保持恒定,在其它情況下窗口大小會增大或減小。

下面是一些你可以用來確定給定問題可能需要滑動窗口的方法:

問題的輸入是一種線性數(shù)據(jù)結(jié)構(gòu),比如鏈表、數(shù)組或字符串

你被要求查找最長/最短的子字符串、子數(shù)組或所需的值

你可以使用滑動窗口模式處理的常見問題:

大小為 K 的子數(shù)組的最大和(簡單)

帶有 K 個不同字符的最長子字符串(中等)

尋找字符相同但排序不一樣的字符串(困難)

2.二指針或迭代器

二指針(Two Pointers)是這樣一種模式:兩個指針以一前一后的模式在數(shù)據(jù)結(jié)構(gòu)中迭代,直到一個或兩個指針達到某種特定條件。二指針通常在排序數(shù)組或鏈表中搜索配對時很有用;比如當(dāng)你必須將一個數(shù)組的每個元素與其它元素做比較時。

二指針是很有用的,因為如果只有一個指針,你必須繼續(xù)在數(shù)組中循環(huán)回來才能找到答案。這種使用單個迭代器進行來回在時間和空間復(fù)雜度上都很低效——這個概念被稱為「漸進分析(asymptotic analysis)」。盡管使用 1 個指針進行暴力搜索或簡單普通的解決方案也有效果,但這會沿 O(n2) 線得到一些東西。在很多情況中,二指針有助于你尋找有更好空間或運行時間復(fù)雜度的解決方案。

用于識別使用二指針的時機的方法:

可用于你要處理排序數(shù)組(或鏈接列表)并需要查找滿足某些約束的一組元素的問題

數(shù)組中的元素集是配對、三元組甚至子數(shù)組

下面是一些滿足二指針模式的問題:

求一個排序數(shù)組的平方(簡單)

求總和為零的三元組(中等)

比較包含回退(backspace)的字符串(中等)

3.快速和慢速指針

快速和慢速指針方法也被稱為 Hare & Tortoise 算法,該算法會使用兩個在數(shù)組(或序列/鏈表)中以不同速度移動的指針。該方法在處理循環(huán)鏈表或數(shù)組時非常有用。

通過以不同的速度進行移動(比如在一個循環(huán)鏈表中),該算法證明這兩個指針注定會相遇。只要這兩個指針在同一個循環(huán)中,快速指針就會追趕上慢速指針。

如何判別使用快速和慢速模式的時機?

處理鏈表或數(shù)組中的循環(huán)的問題

當(dāng)你需要知道特定元素的位置或鏈表的總長度時

何時應(yīng)該優(yōu)先選擇這種方法,而不是上面提到的二指針方法?

有些情況不適合使用二指針方法,比如在不能反向移動的單鏈接鏈表中。使用快速和慢速模式的一個案例是當(dāng)你想要確定一個鏈表是否為回文(palindrome)時。

下面是一些滿足快速和慢速指針模式的問題:

鏈表循環(huán)(簡單)

回文鏈表(中等)

環(huán)形數(shù)組中的循環(huán)(困難)

4.合并區(qū)間

合并區(qū)間模式是一種處理重疊區(qū)間的有效技術(shù)。在很多涉及區(qū)間的問題中,你既需要找到重疊的區(qū)間,也需要在這些區(qū)間重疊時合并它們。該模式的工作方式為:

給定兩個區(qū)間(a 和 b),這兩個區(qū)間有 6 種不同的互相關(guān)聯(lián)的方式:

理解并識別這六種情況有助于你求解范圍廣泛的問題,從插入?yún)^(qū)間到優(yōu)化區(qū)間合并等。

那么如何確定何時該使用合并區(qū)間模式呢?

如果你被要求得到一個僅含互斥區(qū)間的列表

如果你聽到了術(shù)語「重疊區(qū)間(overlapping intervals)」

合并區(qū)間模式的問題:

區(qū)間交叉(中等)

最大 CPU 負載(困難)

5. 循環(huán)排序

這一模式描述了一種有趣的方法,處理的是涉及包含給定范圍內(nèi)數(shù)值的數(shù)組的問題。循環(huán)排序模式一次會在數(shù)組上迭代一個數(shù)值,如果所迭代的當(dāng)前數(shù)值不在正確的索引處,就將其與其正確索引處的數(shù)值交換。你可以嘗試替換其正確索引處的數(shù)值,但這會帶來 O(n^2) 的復(fù)雜度,這不是最優(yōu)的,因此要用循環(huán)排序模式。

如何識別這種模式?

涉及數(shù)值在給定范圍內(nèi)的排序數(shù)組的問題

如果問題要求你在一個排序/旋轉(zhuǎn)的數(shù)組中找到缺失值/重復(fù)值/最小值

循環(huán)排序模式的問題:

找到缺失值(簡單)

找到最小的缺失的正數(shù)值(中等)

6.原地反轉(zhuǎn)鏈表

在很多問題中,你可能會被要求反轉(zhuǎn)一個鏈表中一組節(jié)點之間的鏈接。通常而言,你需要原地完成這一任務(wù),即使用已有的節(jié)點對象且不占用額外的內(nèi)存。這就是這個模式的用武之地。該模式會從一個指向鏈表頭的變量(current)開始一次反轉(zhuǎn)一個節(jié)點,然后一個變量(previous)將指向已經(jīng)處理過的前一個節(jié)點。以鎖步的方式,在移動到下一個節(jié)點之前將其指向前一個節(jié)點,可實現(xiàn)對當(dāng)前節(jié)點的反轉(zhuǎn)。另外,也將更新變量「previous」,使其總是指向已經(jīng)處理過的前一個節(jié)點。

如何識別使用該模式的時機:

如果你被要求在不使用額外內(nèi)存的前提下反轉(zhuǎn)一個鏈表

原地反轉(zhuǎn)鏈表模式的問題:

反轉(zhuǎn)一個子列表(中等)

反轉(zhuǎn)每個 K 個元素的子列表(中等)

7.樹的寬度優(yōu)先搜索(Tree BFS)

該模式基于寬度優(yōu)先搜索(BFS)技術(shù),可遍歷一個樹并使用一個隊列來跟蹤一個層級的所有節(jié)點,之后再跳轉(zhuǎn)到下一個層級。任何涉及到以逐層級方式遍歷樹的問題都可以使用這種方法有效解決。

Tree BFS 模式的工作方式是:將根節(jié)點推至隊列,然后連續(xù)迭代知道隊列為空。在每次迭代中,我們移除隊列頭部的節(jié)點并「訪問」該節(jié)點。在移除了隊列中的每個節(jié)點之后,我們還將其所有子節(jié)點插入到隊列中。

如何識別 Tree BFS 模式:

如果你被要求以逐層級方式遍歷(或按層級順序遍歷)一個樹

Tree BFS 模式的問題:

二叉樹層級順序遍歷(簡單)

之字型遍歷(Zigzag Traversal)(中等)

8.樹的深度優(yōu)先搜索(Tree DFS)

Tree DFS 是基于深度優(yōu)先搜索(DFS)技術(shù)來遍歷樹。

你可以使用遞歸(或該迭代方法的技術(shù)棧)來在遍歷期間保持對所有之前的(父)節(jié)點的跟蹤。

Tree DFS 模式的工作方式是從樹的根部開始,如果這個節(jié)點不是一個葉節(jié)點,則需要做三件事:

1.決定現(xiàn)在是處理當(dāng)前的節(jié)點(pre-order),或是在處理兩個子節(jié)點之間(in-order),還是在處理兩個子節(jié)點之后(post-order)

為當(dāng)前節(jié)點的兩個子節(jié)點執(zhí)行兩次遞歸調(diào)用以處理它們

如何識別 Tree DFS 模式:

如果你被要求用 in-order、pre-order 或 post-order DFS 來遍歷一個樹

如果問題需要搜索其中節(jié)點更接近葉節(jié)點的東西

Tree DFS 模式的問題:

路徑數(shù)量之和(中等)

一個和的所有路徑(中等)

9. Two Heaps

在很多問題中,我們要將給定的一組元素分為兩部分。為了求解這個問題,我們感興趣的是了解一部分的最小元素以及另一部分的最大元素。這一模式是求解這類問題的一種有效方法。該模式要使用兩個堆(heap):一個用于尋找最小元素的 Min Heap 和一個用于尋找最大元素的 Max Heap。該模式的工作方式是:先將前一半的數(shù)值存儲到 Max Heap,這是由于你要尋找前一半中的最大數(shù)值。然后再將另一半存儲到 Min Heap,因為你要尋找第二半的最小數(shù)值。在任何時候,當(dāng)前數(shù)值列表的中間值都可以根據(jù)這兩個 heap 的頂部元素計算得到。

識別 Two Heaps 模式的方法:

在優(yōu)先級隊列、調(diào)度等場景中有用

如果問題說你需要找到一個集合的最小/最大/中間元素

有時候可用于具有二叉樹數(shù)據(jù)結(jié)構(gòu)的問題

Two Heaps 模式的問題:

查找一個數(shù)值流的中間值(中等)

10. 子集

很多編程面試問題都涉及到處理給定元素集合的排列和組合。子集(Subsets)模式描述了一種用于有效處理所有這些問題的寬度優(yōu)先搜索(BFS)方法。

該模式看起來是這樣:

給定一個集合 [1, 5, 3]

1. 從一個空集開始:[[]]2.向所有已有子集添加第一個數(shù) (1),從而創(chuàng)造新的子集:[[], [1]]3.向所有已有子集添加第二個數(shù) (5):[[], [1], [5], [1,5]]4.向所有已有子集添加第三個數(shù) (3):[[], [1], [5], [1,5], [3], [1,3], [5,3], [1,5,3]]

下面是這種子集模式的一種視覺表示:

如何識別子集模式:

你需要找到給定集合的組合或排列的問題

子集模式的問題:

帶有重復(fù)項的子集(簡單)

通過改變大小寫的字符串排列(中等)

11. 經(jīng)過修改的二叉搜索

只要給定了排序數(shù)組、鏈表或矩陣,并要求尋找一個特定元素,你可以使用的最佳算法就是二叉搜索。這一模式描述了一種用于處理所有涉及二叉搜索的問題的有效方法。

對于一個升序的集合,該模式看起來是這樣的:

1.首先,找到起點和終點的中間位置。尋找中間位置的一種簡單方法是:middle = (start + end) / 2。但這很有可能造成整數(shù)溢出,所以推薦你這樣表示中間位置:middle = start + (end?—?start) / 2。2.如果鍵值(key)等于中間索引處的值,那么返回這個中間位置。3.如果鍵值不等于中間索引處的值:4.檢查 key < arr[middle] 是否成立。如果成立,將搜索約簡到 end = middle?—?15.檢查 key > arr[middle] 是否成立。如果成立,將搜索約簡到 end = middle + 1

下面給出了這種經(jīng)過修改的二叉搜索模式的視覺表示:

經(jīng)過修改的二叉搜索模式的問題:

與順序無關(guān)的二叉搜索(簡單)

在經(jīng)過排序的無限數(shù)組中搜索(中等)

12. 前 K 個元素

任何要求我們找到一個給定集合中前面的/最小的/最常出現(xiàn)的 K 的元素的問題都在這一模式的范圍內(nèi)。

跟蹤 K 個元素的最佳的數(shù)據(jù)結(jié)構(gòu)是 Heap。這一模式會使用 Heap 來求解多個一次性處理一個給定元素集中 K 個元素的問題。該模式是這樣工作的:

1. 根據(jù)問題的不同,將 K 個元素插入到 min-heap 或 max-heap 中2.迭代處理剩余的數(shù),如果你找到一個比 heap 中數(shù)更大的數(shù),那么就移除那個數(shù)并插入這個更大的數(shù)

這里無需排序算法,因為 heap 將為你跟蹤這些元素。

如何識別前 K 個元素模式:

如果你被要求尋找一個給定集合中前面的/最小的/最常出現(xiàn)的 K 的元素

如果你被要求對一個數(shù)值進行排序以找到一個確定元素

前 K 個元素模式的問題:

前面的 K 個數(shù)(簡單)

最常出現(xiàn)的 K 個數(shù)(中等)

13. K 路合并

K 路合并能幫助你求解涉及一組經(jīng)過排序的數(shù)組的問題。

當(dāng)你被給出了 K 個經(jīng)過排序的數(shù)組時,你可以使用 Heap 來有效地執(zhí)行所有數(shù)組的所有元素的排序遍歷。你可以將每個數(shù)組的最小元素推送至 Min Heap 以獲得整體最小值。在獲得了整體最小值后,將來自同一個數(shù)組的下一個元素推送至 heap。然后,重復(fù)這一過程以得到所有元素的排序遍歷結(jié)果。

該模式看起來像這樣:

1.將每個數(shù)組的第一個元素插入 Min Heap2.之后,從該 Heap 取出最?。敳康模┰兀瑢⑵浼尤氲胶喜⒌牧斜?。3.在從 Heap 移除了最小的元素之后,將同一列表的下一個元素插入該 Heap4.重復(fù)步驟 2 和 3,以排序的順序填充合并的列表

如何識別 K 路合并模式:

具有排序數(shù)組、列表或矩陣的問題

如果問題要求你合并排序的列表,找到一個排序列表中的最小元素

K 路合并模式的問題:

合并 K 個排序的列表(中等)

找到和最大的 K 個配對(困難)

14. 拓撲排序

拓撲排序可用于尋找互相依賴的元素的線性順序。比如,如果事件 B 依賴于事件 A,那么 A 在拓撲排序時位于 B 之前。

這個模式定義了一種簡單方法來理解執(zhí)行一組元素的拓撲排序的技術(shù)。

該模式看起來是這樣的:

1.初始化。a)使用 HashMap 將圖(graph)存儲到鄰接的列表中;b)為了查找所有源,使用 HashMap 記錄 in-degree 的數(shù)量2.構(gòu)建圖并找到所有頂點的 in-degree。a)根據(jù)輸入構(gòu)建圖并填充 in-degree HashMap3.尋找所有的源。a)所有 in-degree 為 0 的頂點都是源,并會被存入一個隊列4.排序。a)對于每個源,執(zhí)行以下操作:i)將其加入到排序的列表;ii)根據(jù)圖獲取其所有子節(jié)點;iii)將每個子節(jié)點的 in-degree 減少 1;iv)如果一個子節(jié)點的 in-degree 變?yōu)?0,將其加入到源隊列。b)重復(fù) (a),直到源隊列為空。

如何識別拓撲排序模式:

處理無向有環(huán)圖的問題

如果你被要求以排序順序更新所有對象

如果你有一類遵循特定順序的對象

拓撲排序模式的問題:

任務(wù)調(diào)度(中等)

一個樹的最小高度

在 LeetCode 上殫精竭慮?學(xué)習(xí)過這 14 種模式之后,你能對各種問題的解決方案有一個更全面的認知。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 程序員
    +關(guān)注

    關(guān)注

    4

    文章

    945

    瀏覽量

    29682

原文標(biāo)題:準(zhǔn)備程序員面試?你需要了解這 14 種編程面試模式

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    C語言面試最常問的關(guān)鍵字

    大家好,我是嵌入式老林,從事嵌入式軟件開發(fā)多年,今天分享的內(nèi)容是C語言面試最常問的三個關(guān)鍵字,希望能對你有所幫助。
    發(fā)表于 07-11 12:41 ?295次閱讀

    程序員面試寶典pdf 電子書

    程序員面試寶典取材于各大IT公司歷年面試真題(筆試、口試、電話面試、英語面試,以及邏輯測試和智商測試)。詳細分析了應(yīng)聘程序員(含網(wǎng)絡(luò)、測試等)職位的
    發(fā)表于 09-19 17:20

    電氣自動化專業(yè)面試最常見的問題

    、BJT這3功放電路要會畫,還有3電路的優(yōu)缺點要知道(當(dāng)時我面試就是畫這,別的哥們不會,如果你會的話,我保證要你) 4,電容一般有哪兩?怎么區(qū)別?(不知道的大有人在)電解電容和貼
    發(fā)表于 05-23 16:21

    電工最常見電路

    電工最常見電路
    發(fā)表于 10-12 21:11

    17最常見的開關(guān)電源拓撲

    17最常見的硬開關(guān)電源拓撲
    發(fā)表于 04-26 13:38

    視頻教程:Java常見面試題目深度解析!

    視頻教程:Java常見面試題目深度解析!Java作為目前比較火的計算機語言之一,連續(xù)幾年蟬聯(lián)最受程序員歡迎的計算機語言榜首,因此每年新入職Java程序員也數(shù)不勝數(shù)。很多java程序員在學(xué)成之后,會面
    發(fā)表于 07-11 10:55

    電工最常見電路集

    電工最常見電路集:
    發(fā)表于 02-28 15:39 ?415次下載
    電工<b class='flag-5'>最常見</b>電路集

    探究面試最常見的String、StringBuffer、StringBuilder問題

    一。你了解String類嗎? 二。深入理解String、StringBuffer、StringBuilder 三。不同場景下三個類的性能測試 四。常見的關(guān)于String、StringBuffer
    發(fā)表于 09-27 10:23 ?0次下載
    探究<b class='flag-5'>面試</b><b class='flag-5'>最常見</b>的String、StringBuffer、StringBuilder問題

    編程面試的 9 大算法概念

    以下是在編程面試中排名前 9 的算法相關(guān)的概念,我會通過一些簡單的例子來闡述這些概念。
    的頭像 發(fā)表于 03-20 14:19 ?4235次閱讀
    <b class='flag-5'>編程</b><b class='flag-5'>面試</b>的 9 大算法概念

    Python最常見面試題解答

    Python作為人工智能知識的基礎(chǔ)知識,加上有許多公司都在招python方面的程序員,那么小編在這里整理了一些Python最常見面試題。在python基礎(chǔ)中,很明顯我們需要了解python的特性,像面向?qū)ο笏枷?,字符串的操作,推?dǎo)式,實例化,多線程多進程以及初始化這些都
    的頭像 發(fā)表于 05-12 10:26 ?3376次閱讀

    常見的MySQL高頻面試

    在各類技術(shù)崗位面試中,似乎 MySQL 相關(guān)問題經(jīng)常被問到。無論你面試開發(fā)崗位或運維崗位,總會問幾道數(shù)據(jù)庫問題。經(jīng)常有小伙伴私信我,詢問如何應(yīng)對 MySQL 面試題。其實很多面試題都是
    的頭像 發(fā)表于 02-08 16:05 ?2279次閱讀

    開關(guān)電源最常見的三結(jié)構(gòu)

    開關(guān)電源最常見的三結(jié)構(gòu)布局是降壓(buck)、升壓(boost)和降壓–升壓(buck-boost),這三布局都不是相互隔離的。
    的頭像 發(fā)表于 03-11 17:00 ?7574次閱讀

    關(guān)于數(shù)組常見面試

    數(shù)組是最基本的數(shù)據(jù)結(jié)構(gòu),關(guān)于數(shù)組的面試題也屢見不鮮,本文羅列了一些常見面試題,僅供參考。目前有以下18道題目。
    的頭像 發(fā)表于 08-17 09:25 ?1525次閱讀

    成像雷達系統(tǒng)最常見的極化模式

    成像雷達系統(tǒng)通常發(fā)射平面極化雷達脈沖。與這種脈沖相關(guān)的電場在垂直于波傳播方向的單一平面內(nèi)振蕩。最常見的極化模式是發(fā)射和接收水平極化信號(指定為HH模式,第一個字母表示發(fā)射的極化)。 有些系統(tǒng)發(fā)射
    的頭像 發(fā)表于 06-27 11:25 ?3475次閱讀
    成像雷達系統(tǒng)<b class='flag-5'>最常見</b>的極化<b class='flag-5'>模式</b>

    最常見的五電機冷卻方式介紹

    電機的冷卻方式通常根據(jù)其功率、運行環(huán)境和設(shè)計要求來選擇。以下是五最常見的五電機冷卻方式
    發(fā)表于 08-16 09:29 ?4405次閱讀