Leetcode array Top Interview Questions 32道題總結

本篇文章是對leetcode array和Top Interview Questions標籤下32道array類型題目的總結

leetcode 283. Move Zeroes
此題屬於數組交換型,交換數組中元素的位置以滿足某種條件
解:交換數組位置,一般使用兩個指針的辦法,已到達O(1) space 的效果
並且此題有個特殊之處,題目中將數組中的元素分爲0項和非0項,也可分爲數組分類型,數組分類型的問題,假如有n個類,往往不必全部考慮這n個類,只要將n-1個類處理完,那最後一類自然被處理完。如本題中,只要處理了非0類,那麼0類的數自然排到了末尾。

leetcode 169. Majority Element
此題屬於數組計數問題,要找到數組中出現次數最多的那個數
解:

  1. 首先觀察本題,發現此題可以從大問題分解爲小問題,因此非常適合使用分治法
  2. 多數投票算法(Boyer-Moore Voting Algorithm)
    論文翻譯:假設有一羣投票的人,每個人都會投票個某個候選人。爲了選擇最終贏的選取的候選人,可以採用這樣的選舉方式:每個投票人找到其他的投票人,並且這個投票人支持的候選不同於自己的支持的候選人,PK過後,這一對投票人同時出局。經過全部的PK之後,那麼還沒有出局的投票人支持的候選人,就有可能是最終的選舉勝利者(獲得半數以上的選票)。最後,選舉主席,需要檢查這位可能贏得選舉的候選人的票數,來確認他是否贏得了選舉。
    https://www.cnblogs.com/javanerd/p/6262249.html
    因此,數組計數問題可以考慮摩爾投票算法
  3. 數字數量上的問題,最後會反應到32位上的每一位,因此可以從位操作的角度出發

leetcode 268. Missing Number
此題的特點在於限制了數組中出現數的範圍,尋找缺失的那一個
解:

  1. 根據數組的和與每個數的關係,可以得到缺失數
  2. 數組位置i及其存儲的值nums[i] 之間的關係,因爲一個數異或它本身爲0,而數組位置0~n-1,數組存儲的值包含 0 ~ n,又因爲異或具有交換律,所以將數組位置 i 與nums[i]異或,最後的結果便是缺失的數

leetcode 1. Two Sum
尋找數組中是否有特定的數,可以通過hash來減少查找時間
解:

  1. 使用hash減少查找時間,因爲用hash可以達到O(1)的查找時間

leetcode 53. Maximum Subarray
尋找數組中的連續最大和子序列,屬於尋找數組區間(不像上一道題是尋找某個數)
解:

  1. 觀察本題,發現此題仍然可以從大問題分解爲小問題,因此使用分治法
  2. 動態規劃,區間的問題非常適合動態規劃。而且發現在數組中,i 位置的情況是和 i-1情況相關的,因此使用dp
  3. 貪心, 發現 i 位置只需要依賴 i-1 位置的情況(在 i-1 情況明確時), 可以將動態規劃簡化爲貪心

leetcode 26. Remove Duplicates from Sorted Array
此題特點:數組元素出現重複
解:

  1. 使用兩根指針,一根指非重複數字,一根指向重複數字,並通過while循環跳過重複數組
  2. 也可看做數組分類問題

Leectode 88. Merge Sorted Array
此題特點:合併問題
解:

  1. 使用兩根指針,合併時從後往前合併,這樣就不需要考慮從前往後排時,要將後面的數字統一往後移動一格的問題。正向遍歷困難時,通常可以考慮反向遍歷

Leetcode 189. Rotate Array
此題特點:數組反轉
解:

  1. 使用循環替代
  2. 先反轉整個數組,然後再翻轉前k個元素,再翻轉後n-k個元素

leetcode 238. Product of Array Except Self
此題特點:數組區間
解:

  1. 使用兩個動態數組。leftDp[i] 表示i左邊的數的乘積,rightDp[i] 表示i右邊的數的乘積,那麼res[i] = leftDp[i] * leftDp[i]
  2. 發現 i 只與 i-1/i+1有關,因此可以將動態數組簡化爲1個變量

leetcode 78. Subsets
得到數組中所有的子集,屬於排列組合型
解:

  1. 回溯法,find裏面的循環是尋找第n層遞歸的起點,依次從前往後添加元素,以避免重複,第n層遞歸時,添加長度爲n的子集。要注意,回溯爲了消除前一次的影響,在回溯完之後,要移除回溯前添加的數

leetcode 287. Find the Duplicate Number
此題特點:數組重複
解:

  1. 檢測重複問題,可以使用環檢測算法,兩根指針
    https://blog.csdn.net/xyzxiaoxiong/article/details/78761940
  2. 二分查找
    使用鴿籠原理,當數組內的數<= mid的個數多餘mid時,將search範圍放在mid~high,
    當個數小於等於mid時,將search範圍放在low~mid,最後返回low/high(指的是索引)
    巧妙的運用二分法
    如n=10,mid=5,如果數組內小於等於5的個數多餘5個,那麼根據鴿籠原理,重複的數必在1~5內

leetcode 48. Rotate Image
特點:屬於數組交換問題,交換位置
解:

  1. 先根據斜對稱軸對摺,再根據中線y軸對摺

leetcode 62. Unique Paths
特點:沒有特點
解:

  1. 很明顯的動態規劃,數組 位置 i 上的情況依賴於附近位置的情況

Leetcode 289. Game of Life
特點: 根據某個規則,修個整個數組
解:

  1. 使用輔助數組,記錄修改之前的情況
  2. 不適用輔助數組,在原位置做標記,標記該位置做了修改或者需要修改,要注意做的標記不會影響到邏輯判斷

leetcode 11. Container With Most Water
特點:尋找符合要求的數組區間
解:

  1. 使用兩根指針,思考邏輯鏈:算面積->需要知道長寬-> 寬的話取決於兩邊短的一邊-> 兩邊-> 兩個指針法
    每次移動短的那一段,因爲如果移動大的,那麼在另一端不變的情況下,水量可能會變小,首先寬變小一位,而高度始終是以小的算的。相對來說移動小的,在寬度變小的情況下,更容易獲得更大的面積

leetcode 75. Sort Colors
特點: 數組交換,數組分類問題
解:

  1. 將數組分爲三類0類、1類、2類,對0和1兩類進行交換,當交換完成時,2類也自動完成
    需要在數組上交換而不引入額外空間-> 兩根指針

leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
特點:並無什麼特點

leetcode 79. Word Search
解:

  1. 回溯法,記錄訪問軌跡,注意在這個分支回溯完成後,需要把訪問數組中該位置置回原來的值
  2. 也可以不適用輔助數組記錄訪問,可以訪問時將本位置的數標記,置爲不會影響邏輯的其他數字,回溯完成時重新置回原來的數,這裏有一個問題,難道不記錄原來的數是什麼嗎?使用異或的性質,一個數異或本身爲0, 設原來的數爲A,回溯前A^256, 回溯後A ^ 256 就變回原來的A了

leetcode 73. Set Matrix Zeroes
特點:根據某項規則,修改整個數組
解:

  1. 使用輔助數組
  2. 進行標記,但要注意,這裏標記如果原位置標記的話,會對後面的判斷造成影響,所以對行首/列首進行標記。這樣只需要對行首/列首單獨處理即可

leetcode 162. Find Peak Element
尋找數組中是否有特定的數,使用二分查找
解:

  1. 線性掃描,遍歷每一個數,比較是否左邊的數要低一點,右邊的數要高一點。當然,如果發現右邊的數要低一點,就沒有必要再看右邊的數是否符合,直接看右邊的數的下一個數
  2. 這樣的題使用二分查找,一開始還是很驚奇的,因爲印象中都是對有序數組才使用二分法,但這是對二分法的誤解,要理解二分法的精髓在於在每一步都減少待搜索的區間
    考慮本題,一個數mid根據和其右邊的數進行比較,可以得到該數是在下降的斜坡上還是在上升的斜坡,如果右邊的數更小,可以認爲是在下降的斜坡上,那麼峯值一定是在mid的左邊(包含其本身);如果右邊的數更大,可以認爲是在上升的斜坡上,那麼峯值一定是在mid的右邊,所以搜索範圍可以限制在mid及其右邊的子數組
    當然,比如右邊的數比mid更大,是在上升的斜坡中,將捨棄mid左邊的子數組中也可能存在peak元素,但本題不是求最大的數,本題只要求找到一個peak即可,甚至邊界值(i=0,i=n-1)也算peak,所以纔可以這樣使用二分法
    使用二分法減少搜索空間

leetcode 56. Merge Intervals
特點:數組區間問題,排序處理
解:將每個區間進行排序,按照start進行排序,start小的排在前面,遍歷排序後的intervals,如果第n個interval的end < 第n+1個的interval的start,那麼就將第n個interval當作一個新的interval加入結果中。如果第n個interval的end >= 第n+1個的interval的start,那麼就進行合併,end取兩個區間中最大那一個

leetcode 34. Find First and Last Position of Element in Sorted Array
特定: 尋找數組中特定的數,使用二分查找
解:

  1. 遍歷數組找到最大最小
  2. 使用二分查找,減小搜索空間。
    按照正常binary search首先在mid處找到一個target,因爲數組已經排序好了,如果還有其他的target,那一定是在target的左邊還有右邊,如果有,那就分別以mid-1作爲最右邊界/mid+1作爲最左邊界繼續查找,得到position更小/更大的數

leetcode 33.Search in Rotated Sorted Array
特點:尋找數組中特定的數,使用二分查找
解:

  1. 觀察題目發現,因爲數組被旋轉了,所以可以確定,左邊被旋轉的那一部分的第一個數比右邊被旋轉的部分都大,右邊被旋轉的最後一個數也是比左邊被旋轉的所有數都小,所以每次二分查找時,判斷mid的左邊和右邊是否正常,比較target和nums[start]的大小關係,如果nums[start] 比 target大,說明target應該位於mid的右邊

leetcode 55. Jump Game
特點:
解:

  1. 自頂向下動態規劃,從method 1中我們可以看出,有些位置會重複遍歷,因此我們引入記憶化搜索,還會回溯,但每到一個位置i時,先查看該位置是否是能夠到達終點的位置(GOOD), 還是不能到達終點的位置(BAD),如果是不知道的位置(UNKNOWN),則遍歷這個位置
    通過使用dp降低了複雜度,存儲了index i是否能到達終點的結果,當再經過這些index的時候不再需要計算!
  2. 從method 3 中再次得到啓發,如果在位置i,且i~nums[i]+i這之中有一個GOOD INDEX,那麼代表位置i也是個GOOD INDEX
    遍歷完如果lastPos = 0 則表示起點也是good Index,那麼從起點也可以跳到終點
  3. 當方法超時的時候)發現是不是有些步驟被重複計算,如果有重複計算,那麼就引入動態規劃
  4. 反向思考,問的是從起點到終點,如果能從終點到起點,結果也是等價的

leetcode 54. Spiral Matrix
特點:遍歷數組
解:

  1. method1 中 if和else過多過於繁雜,觀察題目我們可以發現,遍歷的方向是有順序的,永遠是往右,往下,往左,往上。因此,我們可以通過加法+求餘來得到下一個方向,因此,也能夠知道x,y該加還是該減,還是該不變
    dr 表示row上的操作,dc 表示在column上的操作,當往左或往右時,行數不變,因此dr[0]/dr[2]都爲0
    如果遍歷的方向是有規律的,是有循環的,那麼可以使用加法和求餘來控制方向!

leetcode 152. Maximum Product Subarray
特定:數組區間型
解:

  1. 單純用Maximum Sum Subarray的方法來做本道題是錯的,問題就在於dp[1]可能不僅和dp[i-1]有關,甚至和dp[i-2]有關,例如負,正,負的情況,在這樣的情況下,dp不僅需要記錄以i-1結尾的最大積,也需要記錄以i-1結尾的最小積,因爲如果異數相乘,就變成了一個負數
  2. 使用一個變量代替數組,當動態規劃數組中,dp[i]只與dp[i-1]相關,那麼這個時候可以用一個變量代替dp數組
  3. 動態規劃中弄清楚,當前位置的數究竟和附近哪幾個位置有關

leetcode 15. 3Sum
特點:尋找數組中特定的數
解:

  1. 3sum問題轉換爲2sum問題,然後再用2sum的辦法解決。這裏使用兩個指針的方
  2. 在使用兩根指針的時候,考慮一下是否需要排序,讓指針的移動更具有方向性
  3. 當處理去除重複性問題時,既可以使用set自動去重,也可以進行排序,當數重複的時候便跳過

leetcode 42. Trapping Rain Water
特定: 和leetcode 11一樣,着眼於每個位置i能夠積累多少水
解:

  1. 先找到數組中bar高度最高中最後一個的索引(因爲可能存在多個高度一樣的bar)
    還是以每個位置i上能積累多少水量的思想計算,從左往右遍歷時,每次遍歷到位置i,只要在i+1~maxIndex這片區域中有連續的小於height[i]的bar(j),就證明這個bar可以積累水,並且積水量等於height[i]-height[j]
    從右往左也是相同的
    爲了避免重複計算,會跳過已經計算過水的索引

leetcode 128. Longest Consecutive Sequence
特點:尋找數組區間
解:

  1. 滑動窗口 利用set的特性,不斷地remove
    使用一個set,對每一個數,檢查是否有它的前繼和後繼,如果有則推進,感覺相當於滑動窗口的變種,使用remove方法可以減少遍歷的數據量

leetcode 84. Largest Rectangle in Histogram
特點:數組區間問題
解:

  1. 分治法,RMQ思想,區間最值
    http://dongxicheng.org/structure/lca-rmq/
    https://blog.csdn.net/qq_41311604/article/details/79900893
  2. 等正式複習完補充

leetcode 41. First Missing Positive

leetcode 4. Median of Two Sorted Arrays


問題特點:

  1. 數組交換
    283、48
  2. 數組分類
    26、
  3. 數組計數
    169、
  4. 限制數組中出現數的範圍
    268、
  5. 數組區間
    53、238、11、56、152、128、42、84
  6. 數組元素重複
    26、287
  7. 合併問題
    88、
  8. 排列組合
    78、
  9. 根據某個規則,修改整個數組
    289、73

啓示(array類型問題可以採用的方法):

  1. 兩根指針
    主要是應對數組交換、分類等問題,將space cost限制在O(1)
    如果是重複爲題,通過while循環跳過重複數組
  2. 如果觀察問題,發現問題可以分解爲小的問題,採用分治法
  3. 多數投票算法
  4. 使用位操作解決數字計數問題
  5. 尋找數組中是否有特定的數,可以通過hash來減少查找時間
  6. 如果數組位置i及其存儲的值nums[i] 有對應關係,可以考慮異或
  7. (數組區間)如果發現數組i位置的情況是和 依賴於附近位置情況,那麼可以使用動態規劃
  8. 如果動態規劃中, 發現 i 位置只需要依賴 i-1 位置的情況(在 i-1 情況明確時), 可以將動態規劃簡化爲貪心
  9. 數組反轉
    (1)使用循環代替
    (2)先反轉整個數組,然後再翻轉前k個元素,再翻轉後n-k個元素
  10. 排列組合型,使用回溯法,find裏面的循環是尋找第n層遞歸的起點,依次從前往後添加元素,以避免重複,第n層遞歸時,添加長度爲n的子集。要注意,回溯爲了消除前一次的影響,在回溯完之後,要移除回溯前添加的數
  11. 檢測重複問題,也可以使用兩根指針,使用環檢測算法
  12. 二分查找,查找數組中的某個數,可以使用二分查找減少數組的搜索空間,不一定要求數組是有序的,只要能夠按照二分查找的思想,每次捨棄一半的無用的查找空間
    (1)leetcode 287
    使用鴿籠原理,當數組內的數<= mid的個數多餘mid時,將search範圍放在mid~high,
    當個數小於等於mid時,將search範圍放在low~mid,最後返回low/high(指的是索引)
    巧妙的運用二分法
    如n=10,mid=5,如果數組內小於等於5的個數多餘5個,那麼根據鴿籠原理,重複的數必在1~5內
    (2)leetcode 162
    這樣的題使用二分查找,一開始還是很驚奇的,因爲印象中都是對有序數組才使用二分法,但這是對二分法的誤解,要理解二分法的精髓在於在每一步都減少待搜索的區間
    考慮本題,一個數mid根據和其右邊的數進行比較,可以得到該數是在下降的斜坡上還是在上升的斜坡,如果右邊的數更小,可以認爲是在下降的斜坡上,那麼峯值一定是在mid的左邊(包含其本身);如果右邊的數更大,可以認爲是在上升的斜坡上,那麼峯值一定是在mid的右邊,所以搜索範圍可以限制在mid及其右邊的子數組
    (3)leetcode 34
    按照正常binary search首先在mid處找到一個target,因爲數組已經排序好了,如果還有其他的target,那一定是在target的左邊還有右邊,如果有,那就分別以mid-1作爲最右邊界/mid+1作爲最左邊界繼續查找,得到position更小/更大的數
    (4)leetcode 33
    觀察題目發現,因爲數組被旋轉了,所以可以確定,左邊被旋轉的那一部分的第一個數比右邊被旋轉的部分都大,右邊被旋轉的最後一個數也是比左邊被旋轉的所有數都小,所以每次二分查找時,判斷mid的左邊和右邊是否正常,比較target和nums[start]的大小關係,如果nums[start] 比 target大,說明target應該位於mid的右邊
  13. 回溯,根據某個規則,修改整個數組
    (1)可以使用輔助數組
    (2)不使用輔助數組,在原位置上做標記,要注意做的標記不會影響到邏輯判斷
    (3) 如果是在回溯中做標記,爲了不記憶原來的數,使用異或的性質,一個數異或本身爲0, 設原來的數爲A,回溯前A^256, 回溯後A ^ 256 就變回原來的A了
    (4)進行標記時要注意 這裏標記如果原位置標記的話,會對後面的判斷造成影響,所以對行首/列首進行標記。這樣只需要對行首/列首單獨處理即可
  14. 先對數組排序再處理,往往能減少複雜度
  15. 當方法超時的時候)發現是不是有些步驟被重複計算,如果有重複計算,那麼就引入動態規劃
  16. 反向遍歷,反向思考,問的是從起點到終點,如果能從終點到起點,結果也是等價的。
  17. 使用數組來控制遍歷的方向
    遍歷的方向是有順序的,永遠是往右,往下,往左,往上。因此,我們可以通過加法+求餘來得到下一個方向,因此,也能夠知道x,y該加還是該減,還是該不變
    dr 表示row上的操作,dc 表示在column上的操作,當往左或往右時,行數不變,因此dr[0]/dr[2]都爲0
    如果遍歷的方向是有規律的,是有循環的,那麼可以使用加法和求餘來控制方向!
  18. 動態規劃中弄清楚,當前位置的數究竟和附近哪幾個位置有關
  19. 在使用兩根指針的時候,考慮一下是否需要排序,讓指針的移動更具有方向性
  20. 當處理去除重複性問題時,既可以使用set自動去重,也可以進行排序,當數重複的時候便跳過
  21. 對於數組區間問題,可以考慮使用滑動窗口問題,同時通過hash減少查找時間,將查找時間限制在O(1)

簡略版:

  1. 兩根指針
  2. 二分查找
  3. 分治法
  4. 回溯
  5. 動態規劃
  6. 貪心
  7. hash減少查找時間(set/map)
  8. 位操作 異或
  9. 多數投票算法
  10. 環檢測算法
  11. 環檢測算法
  12. 反向遍歷
  13. 排序
  14. 數組控制遍歷方向
  15. 滑動窗口
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章