[東哥的leetcode刷題日記] leetcode刷題計劃及分類總結

本人今年應屆剛入職杭州某IT企業,日常工作中深感自身算法和代碼能力薄弱,之前找工作雖然也刷過leetcode,但找到工作後並沒有堅持下來,因此想開個刷題專欄監督自己,希望能夠提升自身coding能力~ 如有錯誤或者更優解法,還請評論指出~
本文爲刷題前在網上尋覓的刷題計劃及分類總結,覺得非常有用,打算按照題目tag來刷,先刷每個tag中的easy和medium題。
本文參考博客園的“fish1996”大佬寫的博客,感謝大佬的分類總結。因爲本人喜愛markdown的風格,因此將其改寫成了markdown格式,以便進行檢索,後續根據刷題進程不斷細分類別,希望能夠對大家有所幫助。

數組操作

1 https://leetcode-cn.com/problems/two-sum/

初始化1個hashmap,一次遍歷即可完成。判斷target - nums[i]是否在hashmap中,如果在就返回結果,如果不在就將nums[i]插入到hashmap中。

26 https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

單指針法/雙指針法進行數組去除重複元素

35 https://leetcode-cn.com/problems/search-insert-position/

經典二分法,需要注意邊界條件


滑動窗口

3 https://leetcode.com/problems/longest-substring-without-repeating-characters/

維護一個不含重複字符的滑動窗口。需要記錄每個字符最後出現的位置,當遇到重複字符的時候,就把窗口首部調到上一次出現這個字符的下一個位置。

76 https://leetcode.com/problems/minimum-window-substring/

滑動窗口題。維護一個包含t中所有字符的最小滑動窗口,首先用一個hashmap記錄所有t中的字符和出現次數,在s中每遇到一次計數器加一,找到了符合條件的窗口後,嘗試向右移動窗口左指針,直到恰好能夠滿足條件爲止。更新當前最小滑動窗口。

209 https://leetcode.com/problems/minimum-size-subarray-sum/

維護一個大於等於sum的最小滑動窗口。

239 https://leetcode.com/problems/sliding-window-maximum/

求滑動窗口中的最大值。(1) 使用ordered_map,動態更新,取首元素, NlogK。(2) 維護一個指向最大值的指針,當指針不再在窗口內時,向後移動這一指針到合適的位置。最壞時間複雜度是O(NK),但均攤表現比1還要好。(3)使用單調隊列,維護單調遞減的隊列,隊首不再在窗口內時彈出隊首,有更大的元素彈出隊尾。當前最大元素爲隊尾元素。接近O(N)。

424 https://leetcode.com/problems/longest-repeating-character-replacement/

維護一個最多包含k個額外字符的滑動窗口。需要記錄當前出現次數最多字符的出現次數來判斷窗口是否合法,如果超過了,就把首指針向後挪一位,同時更新最多出現次數。對每個合法窗口,取其中的最大值。

438 https://leetcode.com/problems/find-all-anagrams-in-a-string

主要思路是維護兩個hashmap,一個記錄期望出現的字符,一個記錄當前出現的字符。當前出現的字符隨着窗口滾動不停更新,每次移動窗口後,都判斷當前窗口是否滿足條件。同時維護一個滿足條件的count變量,通過比較當前出現字符和期望出現字符的個數來更新,當count等於期望字符串的長度時,意味着當前窗口滿足條件。

480 https://leetcode.com/problems/sliding-window-median/

求滑動窗口的中位值。可以維護一個mutilmap。

576 https://leetcode.com/problems/permutation-in-string/

同438。

904 https://leetcode.com/problems/fruit-into-baskets/

查找最多出現k個字符的最大滑動窗口。可以維護一個包含所有字符出現最後下標的哈希表,每次查到數字超過k個,就把begin指針移到最小的最後出現下標的下一個。

978 https://leetcode.com/problems/longest-turbulent-subarray/

檢查前後兩個數字是否滿足大於或者小於的關係,如果滿足計數器加一,否則清空。掃描兩次處理奇數偶數情況。

992 https://leetcode.com/problems/subarrays-with-k-different-intergers

計算滑動窗口中恰好出現k個不同字符的窗口數目。這道題的一個可以通過的暴力算法是n2的,找到一個滿足條件的滑動窗口後,把begin指針後移,直到不到滿足爲止。統計出現個數。我們需要維護一個可以快速找到k個數字中,最後出現位置最早的那個數字出現的位置,使我們能夠快速移動begin指針。

1004 https://leetcode.com/problems/max-consecutive-ones-iii/

維護最多包含k個0的滑動窗口,一旦超過了k個0,把隊首的0 pop出來。不斷更新當前滑動窗口中的數據個數,並取最大值返回即可。


排列

31 https://leetcode.com/problems/next-permutation/

找到下一個排列數。從右到左找到第一個nums[ i ] < nums[ i + 1]的pair,然後在後面找到比nums[ i ] 大的最小數字,把它交換過來。i 之後的數字也一一交換。

46 https://leetcode.com/problems/permutations/

輸出所有排列數。遞歸中,最快的方法是直接交換,實際上執行的是選擇操作,選擇了一個數據後,把它交換到前面;可以保證下一次選擇不會包含着一數字,並且數字被選擇的概率都是相等的。

47 https://leetcode.com/problems/permutations-ii/

輸出所有的排列數(帶重複)。在選擇的時候,使用hashmap記錄在位置i處選過的數據,避免選擇了重複的數據。

60 https://leetcode.com/problems/permutation-sequence

求第k個排列數。數學解法,可以找一下規律。比如對於1234的排列數,一共有24種。我們從左到右依次決定排列數是哪些。首先第一個數有4種可選的,一共有24種,那麼每種就是6個,我們用 k / 6,看它落在哪個區間,就取哪個數字。

之後,還有三個數可選,因爲一共有6種,所以每種有2個,我們計算k / 2……以此類推得到所有位的數字。因爲k從0計數算起來更簡單,所以我們一開始做k–。

996 https://leetcode.com/problems/number-of-squareful-arrays/

這道題要求找到滿足條件的排列數個數。可以在生成排列數的同時檢查是否滿足條件。


動態規劃

求最大面積的:題號85(最大面積矩形) 221(最大面積正方形) 1139(最大面積邊框正方形)

5 https://leetcode.com/problems/longest-palindromic-substring/

爬臺階類型問題。考慮字符串的中心字符會更加方便,爲了處理奇數和偶數,可以開成2 * n - 1的dp。或者直接從中心往兩邊擴展,查找最長的。

10 https://leetcode.com/problems/regular-expression-matching/

匹配類型問題。狀態方程稍微有些麻煩,如果當前匹配(包括.匹配),則從i - 1, j - 1轉換到i ,j ,但如果當前匹配爲 ,因爲可代表匹配0個,可選擇匹配或不匹配。

32 https://leetcode.com/problems/longest-valid-parentheses/

最長子串類型問題。

44 https://leetcode.com/problems/wildcard-matching/

匹配類型問題。

62 https://leetcode.com/problems/unique-paths/

爬臺階類型問題。從上方或左方彙總結果。

63 https://leetcode.com/problems/unique-paths-ii

爬臺階類型問題。從上方或左方彙總結果,有障礙則不彙總。

64 https://leetcode.com/problems/minimum-path-sum/

爬臺階類型問題。從上方或左方疊加最小值。

72 https://leetcode.com/problems/edit-distance/

爬臺階類型問題(2D)。要麼選擇替換,要麼選擇添加一個,選擇其中轉換次數最小的。

85 https://leetcode.com/problems/maximal-rectangle/

最大面積問題。先計算每一列的前綴和,可以把每一行看作橫座標,當前的值看作高度,得到一個直方圖一樣的東西,接下來只需計算直方圖中的最大矩形面積。時間複雜度O(N3),用單調棧做是O(N2)

87 https://leetcode.com/problems/scramble-string/

記憶化搜索。在所有可能的交換結果中找是否存在滿足條件的。

91 https://leetcode.com/problems/decode-ways

爬臺階類型問題。當前要麼解析一個字節,要麼解析兩個字節。

95 https://leetcode.com/problems/unique-binary-search-trees-ii/

記憶化搜索。權值在(i, j) 之間的樹可以存起來,作爲更大的樹的子樹。

96 https://leetcode.com/problems/unique-binary-search-trees-ii/

爬臺階類型問題。同上,但無需存儲所有結果了。從左右子樹彙總結果。

97 https://leetcode.com/problems/interleaving-string/

匹配類型問題。需從多種選擇中找到滿足條件的。

115 https://leetcode.com/problems/distinct-subsequences/

匹配類型問題。

120: https://leetcode.com/problems/triangle/

爬臺階類型問題。相當於帶權重的一次爬臺階。

123 https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

分治。分成兩部分,疊加兩邊最大的結果。

132 https://leetcode.com/problems/palindrome-partitioning-ii/

劃分類型問題。先計算出所有可能的迴文串,dp[ i ] 代表前 i 個字符的最小劃分,找到以 i 結尾的所有迴文串,取劃分最小的那個作爲結果。

139 https://leetcode.com/problems/word-break/

劃分類型問題。

140 https://leetcode.com/problems/word-break-ii

劃分類型問題。和139差不多,但是有些test case 實在太煩人了。

152 https://leetcode.com/problems/maximum-product-subarray

多狀態轉換類型問題。需要維護當前的最大值和最小值,在兩者之間因爲正負數可以發生轉換。

174 https://leetcode.com/problems/dungeon-game/

爬臺階類型問題。但是需要從終點到起點反向求解,才能得到合法的遞推關係,記錄的是到達當前位置需要的hp。

188 https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/

多狀態轉換類型問題(帶次數限制)。存在手上持有股票和手上不持有股票狀態,多了一個最大k次交易的限制條件,因爲在狀態轉移方程中,需要多考慮一個k的維度。

213 https://leetcode.com/problems/dungeon-game/

多狀態轉換類型問題。需要考慮當前偷,當前不偷,第一次偷了,第一次沒偷。

221 https://leetcode.com/problems/maximal-square/

最大面積問題。看三個重疊的正方形加上當前位置能否湊成更大的正方形。

264 https://leetcode.com/problems/ugly-number-ii/

數字類問題。大的醜數是小的醜數乘以2,3,5得到的,每次選擇最小的作爲下一個。

279 https://leetcode.com/problems/perfect-squares

數字類問題。查找當前數字減去一個平方數對應的最小拆分次數。

300 https://leetcode.com/problems/longest-increasing-subsequence/

最長子序列問題。經典dp。

304 https://leetcode.com/problems/range-sum-query-2d-immutable/

最大面積問題。類似221。

309 https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/

多狀態轉換類型問題。持有股票狀態,賣出股票狀態,冷卻狀態。

312 https://leetcode.com/problems/burst-balloons

區間題。需要考慮每個區間的長度,從小往大更新。

313 https://leetcode.com/problems/super-ugly-number/

數字類問題。同264。

321 https://leetcode.com/problems/create-maximum-number

分治。左最大 + 右最大的組合中挑一個最大的。

322 https://leetcode.com/problems/coin-change/

揹包類型問題。總金額爲揹包容量,記錄每個金額的最小次數。

338 https://leetcode.com/problems/counting-bits

數字類型問題。簡單dp。

343 https://leetcode.com/problems/integer-break/

數字類型問題。乘積取最大的。

354 https://leetcode.com/problems/russian-doll-envelopes/

最大子序列問題。二分法做速度會更快。

357 https://leetcode.com/problems/count-numbers-with-unique-digits

數字類型問題。

363 https://leetcode.com/problems/max-sum-of-rectangle-no-larger-than-k

最大面積問題。同時用到了二分,思考這道題可以先從數組入手,再擴展到矩陣。

368 https://leetcode.com/problems/largest-divisible-subset/

最長子序列和問題。不僅需要求出最長的,還需要輸出最長的,所以需要記錄路徑。

375 https://leetcode.com/problems/guess-number-higher-or-lower-ii

分治。在最優解下,取左右最大的 + k。問題描述讓人很困惑,不知道它需要的是最優解下的情況。

416 https://leetcode.com/problems/partition-equal-subset-sum/

揹包類型問題。總和的一半爲揹包總容量,找到能夠恰好填滿揹包的物體。

647 https://leetcode.com/problems/palindromic-substrings/

爬臺階類型問題。迴文子串個數,爲了處理奇偶迴文,可以開一個2 * n + 1長度的dp容器。

650 https://leetcode.com/problems/2-keys-keyboard/

爬臺階類型問題。狀態可由上一個因數轉換過來。

673 https://leetcode.com/problems/number-of-longest-increasing-subsequence/

最長子序列類型問題。需要開兩個數組,在維護最長長度的同時更新最長長度的數量。

714 https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/

多狀態轉換類型問題。存在手上持有股票和手上不持有股票狀態。

740 https://leetcode.com/problems/delete-and-earn/

爬臺階類型問題。根據當前數字和前一數字相差是否爲1決定從前一數字轉換到當前數字,還是從前前一數字轉換到當前數字。

764 https://leetcode.com/submissions/detail/234958158/

計算每個格子四邊最長的1。

801 https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/

多狀態轉換問題。交換和不交換兩種。

808 https://leetcode.com/problems/soup-servings

記憶化搜索。直接模擬題意即可,但有一個數學上的trick,並沒有想到。

813 https://leetcode.com/problems/largest-sum-of-averages

劃分類型問題(帶次數限制)。遞推考慮的不只是從前i個數字到前i + 1個數字,還需要考慮從劃分爲k到劃分爲k + 1組,相當於在後面疊加一組。

877 https://leetcode.com/problems/stone-game/

拿左拿右取最大的那種結果。非遞歸寫法是從後往前推導。

931 https://leetcode.com/problems/minimum-falling-path-sum/

爬臺階類型問題。可以從上一層的左中右選擇最小的。

935 https://leetcode.com/problems/knight-dialer

爬臺階類型問題。n + 1長度的從n 長度的累加得到。

956 https://leetcode.com/problems/tallest-billboard

揹包類型問題。要點在於記錄的是兩個揹包的差值。

960 https://leetcode.com/problems/delete-columns-to-make-sorted-iii/

最長子序列類型問題。求n個字符串都符合的最長字典序子序列即可。

983 https://leetcode.com/problems/minimum-cost-for-tickets/

揹包類型問題。一年總天數爲揹包容量。

1024 https://leetcode.com/problems/video-stitching/

揹包類型問題。片段總長度爲揹包容量。

1027 https://leetcode.com/problems/longest-arithmetic-sequence/description/

最長子序列類型問題。之前狀態可存hash中。

1039 https://leetcode.com/problems/minimum-score-triangulation-of-polygon/

記憶化搜索。需要以邊作爲子問題劃分的基礎。

1043 https://leetcode.com/problems/partition-array-for-maximum-sum/

限制長度的劃分。注意劃分爲k個連續集合,和劃分的連續集合中最多k個數字,以及劃分爲k個可不連續的子集的區別。

1048 https://leetcode.com/problems/longest-string-chain/

爬臺階類型問題。從k - 1長度轉換到k長度,取其中總長最大的。

  1. https://leetcode.com/problems/filling-bookcase-shelves/

揹包類型問題(2D)。當前書可以單獨放,也可以選擇和前面n本一起放。

1139 https://leetcode.com/problems/largest-1-bordered-square

最大面積問題。類似85,由於是邊框問題,要同時考慮橫向累積和縱向累積,而85只需考慮其中一個就夠了。

1143 https://leetcode.com/problems/longest-common-subsequence/

最長公共子序列。經典dp。

1155 https://leetcode.com/problems/number-of-dice-rolls-with-target-sum/

揹包類型問題。帶次數限制,可多次使用的完全揹包。


區間重疊

56 https://leetcode.com/problems/merge-intervals/

先排序,再逐個檢查當前區間能否和結果隊列中最後一個區間合併。

57 https://leetcode.com/problems/insert-interval/

先把在新區間之前的都加入結果,和新區間存在重疊的取最大最小作爲邊界,在新區間之後的都加入結果。

435 https://leetcode.com/problems/non-overlapping-intervals/

先排序,一旦檢測到重疊,移除end位置比較大的元素。

452 https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/

維護一個當前最小的重疊區域,如果新的區間和這個區間重疊,那麼縮小這個區間,否則重置。每重置一次計數加一。


字典樹

208 https://leetcode.com/problems/implement-trie-prefix-tree/

實現字典樹。包含查詢單詞,和查詢單詞是否包含前綴。

寬度優先搜索

在求單源最短路徑中,我們可能會遇到兩種情況,一種是無權的最短路徑,另一種是有權的最短路徑。

對於無權的最短路徑,因爲我們是按層訪問的,所以我們只需要跟蹤當前搜索層數;一旦我們訪問到了某個結點,那麼當前的層數就一定是到達它的最短路徑。

而對於有權的最短路徑,我們往往採取貪心的策略,在已經確定了最短路徑的結點中,選擇它們相鄰的未訪問過的結點的最小權重路徑,加入訪問結點集合中。

在有權的情況下,我們常常會用到一個dist容器,用於存儲出發點到當前點的最短路徑,並且在發現了更短的路徑後,需要更新dist裏的數據,這是考慮到以下情況:

當我們訪問到藍色結點時,我們會同時更新它的鄰居的最短距離,比如將橙色結點更新爲dist[blue] + 8; 但是此時我們只是確定了藍色結點的路徑是最短的,還無法保證橙色結點的路徑是最短的;因此需要在綠色結點訪問到橙色結點時,更新橙色結點的最短路徑。

102 https://leetcode.com/problems/binary-tree-level-order-traversal/

樹的層次遍歷。基礎題。

126 https://leetcode.com/problems/word-ladder-ii/

單源無權最短路徑。難點在於要記錄所有的路徑。我的做法是先用寬搜得到最短路徑的鄰接關係,之後再利用深搜從後往前歸納所有路徑,然後把路徑倒序。

127 https://leetcode.com/problems/word-ladder/submissions/

單源無權最短路徑。

207 https://leetcode.com/problems/course-schedule/

拓撲排序。計算所有點入度,入度爲0的點放入隊列。每pop一個節點,它的鄰居入度都減一,如果出現了入度爲0的點,再放入隊列。如果訪問的節點數等於課程數,那麼可以完成所有課程。

301 https://leetcode.com/problems/remove-invalid-parentheses/

搜索所有可能的去除組合,判斷是否是有效括號,如果是就加入結果。

310 https://leetcode.com/problems/minimum-height-trees/

類拓撲排序。找到只有一個鄰居的點加入隊列,每pop一個節點,它的鄰居的鄰接表就減去這一節點,直到只剩下一/兩個節點。

513 https://leetcode.com/problems/find-bottom-left-tree-value/

樹的層次遍歷。深搜應該也可以的。

515 https://leetcode.com/problems/find-largest-value-in-each-tree-row/

樹的層次遍歷。

542 https://leetcode.com/problems/01-matrix/

多源無權最短路徑。和單源相比,也就是把所有的0加入起始隊列就可以了。

743 https://leetcode.com/problems/network-delay-time/

單源有權最短路徑。相當於求到每個點的最短路徑,然後去其中最大值。

752 https://leetcode.com/problems/open-the-lock/

單源無權最短路徑。把鎖的狀態記錄爲字符串即可。

773 https://leetcode.com/problems/sliding-puzzle/

單源無權最短路徑。特別的時需要用字符串來記錄所有狀態量,找到目標狀態量後就退出,我們總能保證找到時用到的步數是最少的。

778 https://leetcode.com/problems/swim-in-rising-water/

寬度優先搜索。使用優先隊列,每次選擇值最小的作爲下一個,並更新最大值作爲結果。

787 https://leetcode.com/problems/cheapest-flights-within-k-stops/

單源有權最短路徑。由於有k的次數限制,用寬搜會更加直觀。記錄當前到達終點的最短路徑,如果有更短的,把新的節點加入隊列。

847 https://leetcode.com/problems/shortest-path-visiting-all-nodes/

單源無權最短路徑(帶狀態)。判斷重複節點訪問需要考慮當前狀態:訪問過哪些節點。

854 https://leetcode.com/problems/k-similar-strings/

寬度優先搜索。每次匹配一個字符,第K次後退出。

863 https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/

先從樹建圖,然後做層次遍歷。

864 https://leetcode.com/problems/shortest-path-to-get-all-keys/

單源無權最短路徑(帶狀態)。判斷重複節點訪問需要考慮當前狀態:帶了幾把鑰匙。

909 https://leetcode.com/problems/snakes-and-ladders/

單源無權最短路徑。比較麻煩的一點是要換算位置和對應數字,此外要特殊處理梯子,因爲遇到了梯子/蛇一定要滑過去,所以我們可以當作把這一位置作爲跳板直接到達了梯子末端,就好像沒有來過這一位置一樣。

934 https://leetcode.com/problems/shortest-bridge/

多源無權最短路徑。先用深搜給一個島嶼加上標記,之後的做法就類似於542了,取最小的最短路徑即可。

1091 https://leetcode.com/problems/shortest-path-in-binary-matrix/

單源無權最短路徑。

1129 https://leetcode.com/problems/shortest-path-with-alternating-colors/

單源無權最短路徑,但有限制條件。這道題要求每次走不同顏色的路徑,需要注意的是不同顏色路徑到同一個結點的訪問狀態需要分別維護。

1135 https://leetcode.com/contest/biweekly-contest-5/problems/connecting-cities-with-minimum-cost/

最小生成樹。使用優先隊列, 從一個空集合開始,加入任一頂點,並找到該集合中頂點連接的權重最小的邊,把該邊連接的點也加入集合。直到所有的點都加入了集合,意味着找到了最小生成樹。

1136 https://leetcode.com/contest/biweekly-contest-5/problems/parallel-courses/

拓撲排序。

(1) 對於有向圖,記錄所有頂點的入度(指向該頂點的邊的個數)

(2) 找到所有入度爲0的頂點,把頂點放入隊列

(3) 從隊列pop出一個元素,該頂點則是當前滿足條件的頂點,可將計數加一,並把它指向的頂點的入度都減一,重複(2)(3)直到隊列爲空

(4)如果已經找不到入度爲0的頂點,而當前計數還沒有覆蓋到所有頂點,那麼說明有向圖中可能出現了環路。


深度優先搜索

17 https://leetcode.com/problems/letter-combinations-of-a-phone-number/

暴力搜索所有可能的電話號碼組合。

22 https://leetcode.com/problems/generate-parentheses

暴力搜索所有可能的括號組合。需要傳入當前需要的’(‘和’)'數量。

37 https://leetcode.com/problems/sudoku-solver/

暴力搜索可能的解。發現無法繼續時就回退到上一步。

39 https://leetcode.com/problems/combination-sum/

暴力搜索所有可能的等於sum的組合。爲了避免生成重複,先進行排序,按照非遞減的順序找下一個數字。

40 https://leetcode.com/problems/combination-sum-ii/

暴力搜索所有可能的等於sum的組合。和39相比存在重複,選擇的時候跳過重複即可。

51 https://leetcode.com/problems/n-queens/

回溯。

52 https://leetcode.com/problems/n-queens-ii/

回溯。

90 https://leetcode.com/problems/subsets-ii

暴力搜索所有可能的集合結果。

113 https://leetcode.com/problems/path-sum-ii/

暴力搜索所有可能的等於sum的組合。

133 https://leetcode.com/problems/clone-graph/

遞歸拷貝。如果已經拷貝過,就直接設置指針,沒有拷貝過,就去拷貝。

200 https://leetcode.com/problems/number-of-islands/

每搜索一趟就能遍歷一個島嶼,搜索後加上visit標記,一共搜了幾次就有幾個島嶼。

241 https://leetcode.com/problems/different-ways-to-add-parentheses/

分治。先記錄左邊運算結果,再計算右邊運算結果,最後把兩個結果合併起來。

698 https://leetcode.com/problems/partition-to-k-equal-sum-subsets/

記憶化搜索。首先求出劃分爲k份後每個集合的總和目標值,每次取一個沒有訪問過的數據作爲下一個累加數據,每找到一個目標值後份數減一,目標值重置爲0。看能否恰好減爲0。

417 https://leetcode.com/problems/pacific-atlantic-water-flow/

記憶化搜索。返回值是pair對,記錄當前位置能否到達兩個海洋,如果它能到達的位置能到達海洋,那麼它也能到達。最後掃一遍所有數據,找到兩個都爲true的加入結果。

529 https://leetcode.com/problems/minesweeper/

搜索遍歷。每次掃描到某個空白節點後都判斷它能夠被填充,不能則返回,能則繼續搜索,並修改指向內容,作爲visit訪問標記。

785 https://leetcode.com/problems/is-graph-bipartite/

二分圖判斷。給每個節點染色,並且檢查它的鄰居和它的顏色是否相等,如果存在相等說明不是二分圖。

851 https://leetcode.com/problems/loud-and-rich/

建立有向圖,搜索遍歷所有比它富有的人,取其中最安靜的。

967 https://leetcode.com/problems/numbers-with-same-consecutive-differences/

搜索所有滿足條件的結果。

1034 https://leetcode.com/problems/coloring-a-border/

深度優先搜索。先全塗一個色,然後對邊界和非邊界分別塗色。


42 https://leetcode.com/problems/trapping-rain-water/

維護遞減的單調棧。遇到大於棧頂的,就pop,因爲當前棧頂元素左右兩邊的高度都一定比它高,所以可以同時計算它(橫向的)蓄水量。

84 https://leetcode.com/problems/largest-rectangle-in-histogram

維護遞增的單調棧,當發現當前數字比棧頂要小的時候,此時棧頂元素是最大的(大於棧裏的下一個元素,也大於當前元素),所以可以計算以當前棧頂元素爲高的矩形面積,並比較是不是最大的。

150 https://leetcode.com/problems/evaluate-reverse-polish-notation/

棧模擬遞歸。遇到運算符就pop兩個數字進行計算,並把結果push進去。

316 https://leetcode.com/problems/remove-duplicate-letters/

維護遞增的單調棧。首先,統計每個數字出現的次數,每次訪問過就把出現次數減一。遞增的單調棧對應着最小字典序的結果,已經在棧中的加一個visit標記,避免重複入棧,如果遇到比棧頂更小的,並且棧頂對應的字符在後面也有出現,可以考慮之後再入棧這一字符。所以可以把棧頂pop出來,替換爲新的字符,並更新visit標記。

331 https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/

棧模擬遞歸。這道題需要記錄一個count值,表示當前樹還有多少個地方可以插入新的節點(包括插入數字和插入Null)。如果插入的是數字節點,那麼會多一個可用的位置(新的節點佔用了一個,但又新增了兩個);如果插入的是null,那麼它只會佔用一個,所以會少一個可用的位置。每次遇到沒有可用位置的時候,意味着當前字符串非法。掃描到最後時,如果可用位置還有剩餘,也意味着當前字符串非法。

341 https://leetcode.com/problems/flatten-nested-list-iterator/

棧模擬遞歸。先把所有數據逆序入棧,如果棧頂是數字就直接返回,如果棧頂是鏈表,把鏈表所有值逆序入棧,然後pop當前數據,再循環檢查棧頂是否爲數字。

385 https://leetcode.com/problems/mini-parser/

棧模擬遞歸。解析括號,直接使用遞歸解析更加簡單。

402 https://leetcode.com/problems/remove-k-digits

維護遞增的單調棧。出現了比棧頂小的,就可以移除棧頂的元素,此時k減去1。

456 https://leetcode.com/problems/132-pattern/

維護遞減的單調棧。從後往前遍歷,相當於尋找231paterrn。遇到更大的數就pop出來,同時記錄棧頂的值(作爲第二大的數),之後判斷接下來的值小於這個第二大的數即可。

503 https://leetcode.com/problems/next-greater-element-ii/

維護遞減的單調棧。不過由於題目要求是循環的,需要兩個pass,第二個pass處理循環生效的next greater,同時需要把下標已經超出範圍的隊首數據及時pop出來。

739 https://leetcode.com/problems/daily-temperatures/

維護遞減的單調棧。因爲要找到比它高的第一個溫度,所以遇到遞減的都緩存起來,等到有更高的再一次性更新。

1019 https://leetcode.com/problems/next-greater-node-in-linked-list/

維護遞減的單調棧。這道題對象是鏈表,不像數組可以快速通過下標索引,所以比較方便的做法是在棧中同時記錄數字和對應的下標,並且默認填0,如果找到了比它大的第一個數,再修改下標對應的數字。


二分搜索

4 https://leetcode.com/problems/median-of-two-sorted-arrays/

雙指針二分問題。把兩個數組x,y劃分爲兩個大小相等(或差1)的集合,維護數據maxLeft, minRight,哪邊不滿足maxLeft < minRight就移動一下指針。

11 https://leetcode.com/problems/container-with-most-water/

雙指針二分問題。指針記錄首尾位置,哪邊更矮哪邊的指針向中間移動,同時更新最大容水面積。

15 https://leetcode.com/problems/3sum/

雙指針二分問題。

16 https://leetcode.com/problems/3sum-closest/

雙指針二分問題。對於排好序的數組,首先確定三個數位置在中間的那個數字,然後在它左右搜索另外兩個數,如果大於目標,則右指針左移,否則左指針右移。

18 https://leetcode.com/problems/4sum/

雙指針二分問題。和3sum相比,要先選定兩個數,而不是一個數。

33 https://leetcode.com/problems/search-in-rotated-sorted-array/

根據下標二分問題。檢查二分後的半段是否滿足遞增條件,如果滿足且數據落在這一區間,就在這一區間查找,否則到另一區間查找。

34 https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/

根據下標二分問題。要點是改變low或high的時候把當前數字mid也包含進來,因爲它也可能是結果。

35 https://leetcode-cn.com/problems/search-insert-position/

74 https://leetcode.com/problems/search-a-2d-matrix/

根據下標二分問題。

162 https://leetcode.com/problems/find-peak-element/

根據下標二分問題。每次檢查mid左右兩個數和mid的關係,再決定如何進行下一步。

250 https://leetcode.com/problems/search-a-2d-matrix-ii

雙指針二分問題。從矩陣的右上角開始搜索,到下標越界後退出。

315 https://leetcode.com/problems/count-of-smaller-numbers-after-self/

先額外存一個排序好的數組。然後查找lower_bound,看有多少個數比它小,並把這個數從排序數組中移除。

475 https://leetcode.com/problems/heaters/

二分查找上下界問題。對加熱器進行排序,通過二分查找距離最近的熱水器,並求所有最近距離的最大值。

528 https://leetcode.com/problems/random-pick-with-weight/

二分查找上下界問題。首先計算一個累積的頻數,根據總頻數來進行隨機,之後通過二分查找得到當前隨機數對應的下標。

704 https://leetcode.com/problems/binary-search/

標準二分查找

875 https://leetcode.com/problems/koko-eating-bananas/

二分猜答案問題。也就是在一定的求解空間中找到最小滿足條件的值,使得KoKo能夠以最慢的速度在特定時間內吃完所有香蕉。

911 https://leetcode.com/problems/online-election/

二分查找上下界問題。主要是根據時間來二分,先預先計算好當前時間點對應的選舉人,存到hashmap中。之後通過二分找到時間,再通過hash找到對應選舉人。

1011 https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/

二分猜答案問題。也就是在一定的求解空間中找到最小滿足條件的值,使得貨船能夠以最小的容量在特定時間內運完所有貨物。

1146 https://leetcode.com/problems/snapshot-array/

二分查找上下界問題。每次修改值的時候記錄一下當前快照的值,然後每次查找當前下標特定快照id時的值時,二分查找小於等於這一快照id對應的值即可。

【哈希】(19)

30 https://leetcode.com/problems/substring-with-concatenation-of-all-words/

用hash記錄目標值,從每個下標開始搜索當前字符串是否滿足條件,滿足則加入結果。

36 https://leetcode.com/problems/valid-sudoku/

哈希檢測重複。

49 https://leetcode.com/problems/group-anagrams/

所有的字符串hash到字典序。

347 https://leetcode.com/problems/top-k-frequent-elements/

維護每個數字出現頻率,每個頻率對應數字,然後從高頻率往低搜索。

467 https://leetcode.com/problems/unique-substrings-in-wraparound-string/

哈希計數。遇到特定值的時候就添對應容器加計數,最後把所有計數累加起來得到結果。

523

同560類型題。

560 https://leetcode.com/problems/subarray-sum-equals-k/

使用哈希表記錄之前出現的前綴和sum - k。

781 https://leetcode.com/problems/rabbits-in-forest/

值爲n的可以和其它n + 1個值爲n的成組,統計每個值出現的次數,看它們可以組成多少組相同顏色的兔子,然後乘以組中兔子個數。

890 https://leetcode.com/problems/find-and-replace-pattern/

維護兩個哈希,a中第i位數字和b中第i位數字相互映射,檢測之後的相同數字是否也滿足這種映射。

895 https://leetcode.com/problems/maximum-frequency-stack/

維護兩個哈希。一個哈希記錄每個數字出現的頻率,一個哈希記錄每個頻率出現的數字,因爲可能有多個,可存入棧中。每次取最大頻率對應的棧頂值,並移除。如果最大頻率變爲0,那麼移除這一頻率。

930 https://leetcode.com/problems/binary-subarrays-with-sum/

記錄連續0出現的數字,計算所有(zeros[i] + 1) * (zeros[i + S] + 1)的累加。

954 https://leetcode.com/problems/array-of-doubled-pairs

記錄每個數字出現頻率。按絕對值排序,對於每個數字,查找是否存在2 * x的數字,如果存在,就把它移除,否則返回false。

974 https://leetcode.com/problems/subarray-sums-divisible-by-k/

使用hash記錄當前前綴和%K,如果前面存在相同的數字,那麼意味着存在這樣的連續子數組。

981 https://leetcode.com/problems/time-based-key-value-store/

維護unordered_map<int,map<int,int>>的結果,二分查找每個key對應的時間戳。

1044 https://leetcode.com/problems/longest-duplicate-substring/

哈希字符串匹配。先二分,再哈希查找是否存在長度爲k的重複字符串。

1072 https://leetcode.com/problems/flip-columns-for-maximum-number-of-equal-rows/

假設當前行是結果。查找和它相等,以及和它恰好相反的子串數量,取最大值。

1074 https://leetcode.com/problems/number-of-submatrices-that-sum-to-target/

對任何兩行/列的前綴和,求子數組的前綴和。

1124 https://leetcode.com/problems/longest-well-performing-interval/

等價於找和大於0的最長區間。

1138 https://leetcode.com/problems/alphabet-board-path/

哈希記錄每個字母的下標。按照曼哈頓距離挪過去。


23 https://leetcode.com/problems/merge-k-sorted-lists/

把所有數據加入堆裏,再pop出來構建新鏈表。

215 https://leetcode.com/problems/kth-largest-element-in-an-array/

維護最大爲K的堆。時間複雜度O(NlogK)。

692 https://leetcode.com/problems/top-k-frequent-words/

維護最大爲K的堆。

793 https://leetcode.com/problems/k-closest-points-to-origin/

維護最大爲K的堆。

1383 https://leetcode.com/problems/maximum-performance-of-a-team/

維護最大爲K的堆。這裏首先將所有人按照效率排序,優先選高效的,然後逐步剔除速度慢的人。


並查集

128 https://leetcode.com/problems/longest-consecutive-sequence/

把相鄰元素合併到一個集合中,取數量最大的那個集合作爲結果。哈希的做法是先把所有值放到哈希裏,對每個值查找n+1和n-1的值有哪些,記錄兩端長度。找到了從哈希表中移除。

684 https://leetcode.com/problems/redundant-connection/

類似於最小生成樹。每遇到一對節點把它們Union一下,如果已經在一個集合了,就返回這對邊,說明是要被去掉的。

924 https://leetcode.com/problems/minimize-malware-spread

優先去除所在集合只包含它一個初始節點的初始節點,如果有多個這樣的節點,取集合較大的。如果集合大小一樣,或者該集合包含了多個初始節點,取下標最小的。

【貪心】(10)

45 https://leetcode.com/problems/jump-game-ii/submissions/

可以使用搜索完成。但標準做法是貪心,從當前位置跳到下一個位置時,選擇下一個能跳到最遠位置的地方。

55 https://leetcode.com/problems/jump-game/

暴力算法是n2。貪心思想是從後往前查詢能跳到當前位置的,如果找到了,更新當前位置。最終位置如果能到0就返回true。

134 https://leetcode.com/problems/gas-station

如果A->B無法完成到達,那麼中間也沒有答案(之前累積的結果都是正的,最後一個位置讓它不再爲正數;如果把起始指針向後移動,情況只會更糟);如果氣體總和大於消耗量,那麼必然有解。

378 https://leetcode.com/problems/monotone-increasing-digits/

從後往前遍歷,找到最後一個i + 1小於i的pair,之後的數字都設置爲9,找到小於的時候,把上一個數字減一。

630 https://leetcode.com/problems/course-schedule-iii/

按照結束時間排序,如果當前課程無法在ddl前完成了,就去掉一個時間最長的課程。貪心的標準做法是按結束時間排序後儘可能選,選不了的就放棄。但是這道題的區別在於它的開始時間並不是確定的。

789 https://leetcode.com/problems/escape-the-ghosts/

如果能和鬼在終點相遇,那麼也會在其他地方相遇。

870 https://leetcode.com/problems/advantage-shuffle/

In ordered to maximize the advantage of array A with respect to B, we had better choose the smallest element in array A that is larger than the element in B. After each selection, we erase the data we choose in A to avoid repetition.

948 https://leetcode.com/problems/bag-of-tokens/

排序。從左邊消耗,能量不夠了從右邊取,直到無法補充能量,或首尾指針相遇。

955 https://leetcode.com/problems/delete-columns-to-make-sorted-ii/

從左到右掃描,如果有一個數字不滿足字典序,那麼刪掉該列,否則保留。

1147 https://leetcode.com/problems/longest-chunked-palindrome-decomposition/

左邊右邊開始依次匹配,匹配到了就加一。


94 https://leetcode.com/problems/binary-tree-inorder-traversal/

樹的中序遍歷。非遞歸的做法是使用棧,先入棧所有左子樹,pop出來的時候入棧當前節點的右子樹的所有左子樹。

98 https://leetcode.com/problems/validate-binary-search-tree

檢查是否是合法二叉搜索樹。對於所有結點,檢查是否滿足大於左子樹,小於右子樹。

105 https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

根據中序和前序重建樹。前序第一個作爲根,在中序找到這個數字,左邊的是左子樹,右邊的是右子樹。

144 https://leetcode.com/problems/binary-tree-preorder-traversal/

樹的前序遍歷。非遞歸的做法是使用棧,先入棧右子樹,再入棧左子樹。

145 https://leetcode.com/problems/binary-tree-postorder-traversal/

樹的後序遍歷。非遞歸的做法是使用棧,先入棧左子樹,再入棧右子樹,再把結果反過來。

173 https://leetcode.com/problems/binary-search-tree-iterator/

樹的中序遍歷。查找輸出二叉搜索樹的下一個最大值,相當於使用非遞歸進行中序遍歷。

199 https://leetcode.com/problems/binary-tree-right-side-view/

樹的層次遍歷。輸出每層最後一個結點。

222 https://leetcode.com/problems/count-complete-tree-nodes/

統計完全二叉樹的節點個數。可以先判斷當前子樹是不是滿二叉樹,是的話直接返回2^n - 1,否則遞歸查找。

230 https://leetcode.com/problems/kth-smallest-element-in-a-bst/

中序遍歷,輸出第k個數字。

236 https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/

最小公共祖先。

865 https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes

同1123。

1026 https://leetcode.com/problems/maximum-difference-between-node-and-ancestor/

返回當前節點子節點的最大值和最小值,計算差並更新結果。

1123 https://leetcode.com/problems/lowest-common-ancestor-of-deepest-leaves

最小公共祖先,選擇左右節點中高度比較小的結點對應的答案,如果高度一樣,返回自己。


鏈表

2 https://leetcode.com/problems/add-two-numbers/

19 https://leetcode.com/problems/remove-nth-node-from-end-of-list/

傳說中這道題的標準做法是維護兩個指針,讓一個指針先走n步,然後兩個一起動。第一個指針到盡頭了,第二個指針就是要刪的位置。

24 https://leetcode.com/problems/swap-nodes-in-pairs/

記錄了last,cur,next,nnext指針,交換完了一次跳2格

61 https://leetcode.com/problems/rotate-list/


數學

一些奇怪的找規律題,也不知道是啥類型,就叫數學吧?= =

6 https://leetcode.com/problems/zigzag-conversion/

類似編碼解碼一樣的zigzag打印。

43 https://leetcode.com/problems/multiply-strings/

字符串計算乘法。

48 https://leetcode.com/problems/rotate-image/

打印旋轉矩陣。

54 https://leetcode.com/problems/spiral-matrix/

打印旋轉矩陣。

223 https://leetcode.com/problems/rectangle-area/

計算矩形面積。

228 https://leetcode.com/problems/summary-ranges/

連續數字打印成特定格式。

537 https://leetcode.com/problems/complex-number-multiplication/

計算複數相加。

885 https://leetcode.com/problems/spiral-matrix-iii/

打印旋轉矩陣。

1104 https://leetcode.com/problems/path-in-zigzag-labelled-binary-tree/

zigzag打印2^n.


其它

41 https://leetcode.com/problems/first-missing-positive/

原地排序。把下標對應的數字都交換到下標處。之後再從左到右查到第一個i + 1 != A[i]的元素,即爲答案。

75 https://leetcode.com/problems/sort-colors/

計數排序。

179 https://leetcode.com/problems/largest-number/

排序。將數字轉換爲字符串,比較s1 + s2 和 s2 + s1

229 https://leetcode.com/problems/majority-element-ii/

投票法。3分記兩票。滿足則加一票,爲0則選舉當前,否則都減去一票。

238 https://leetcode.com/submissions/detail/232467850/

計算首尾累積乘積。

287 https://leetcode.com/problems/find-the-duplicate-number/

快慢指針。查找是否存在環。快指針走2步,慢指針走1步,相遇則存在環。設慢指針走了路程s,則快指針走了2s,環長度爲s。若環的起始位置爲d,則慢指針的位置在起始位置過一點的地方,它只要再走d步又可以回到起始位置 。

775 https://leetcode.com/submissions/detail/235207901/

檢查錯位的數字是否都是相鄰的。

807 https://leetcode.com/problems/max-increase-to-keep-city-skyline/

模擬題。

912 https://leetcode.com/problems/sort-an-array/

排序練習。作爲複習,快速排序的做法是:選取一個主元(可取首中尾的中位數,然後把比它小的交換到左邊,比它大的交換到右邊)。每次快排結束,總能保證一個數字被放到了正確位置。

1014 https://leetcode.com/problems/best-sightseeing-pair/

i,j合併同類項,分別求兩個的最大值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章