leetcode題型分類與總結


        刷了兩個半月leetcode,成果如下,以medium為主,加了一些hard。easy不少都是比賽中做的,接下來可能不會大量刷新題了,開始進入總結階段。總結還未開始,本篇文章先占一個坑。

 2020年3月19日更新:本文是去年七月的時候寫的,最近我又開始刷題了,so,這篇文章繼續更新,更新了一下leetcode的刷題數據,加油~

 

 

 

 

 

 

【滑動窗口】(13)

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出來。不斷更新當前滑動窗口中的數據個數,並取最大值返回即可。

【排列】(5)

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/

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

【動態規划】 (66)

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

 

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/

         最長子串類型問題。

        dp[ i ] 代表以i為結尾的最長有效括號字符串的長度。

        如果檢測到s[i + 1] = ')'且s[i - 1 - dp[i] = '(', 則有dp[ i + 1 ] = dp[ i ] + 2; (嵌套括號)

        如果檢測到 以 i - dp[i] 下標為結尾處也對應了有效括號字符串,那么 dp[i + 1] += dp[ i - dp[i] ]  (並列括號)

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長度,取其中總長最大的。

1105. 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/

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

【區間重疊】(4)

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/

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

【字典樹】(1)

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

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

【寬度優先搜索】(25)

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

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

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

        在有權的情況下,我們常常會用到一個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)直到隊列為空

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

【深度優先搜索】(19)

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/

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

【棧】(12)

 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,如果找到了比它大的第一個數,再修改下標對應的數字。

【二分搜索】(18)

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也包含進來,因為它也可能是結果。

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/

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

【堆】(5)

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的堆。這里首先將所有人按照效率排序,優先選高效的,然后逐步剔除速度慢的人。

【並查集】(3)

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/

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

【樹】(13)

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

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

【鏈表】(4)

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/

        

【數學】(9)

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

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.

【其它】(10)

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合並同類項,分別求兩個的最大值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM