演算法思路總結

Tech In Pieces發表於2020-11-12

從解面試中的演算法題目的方面來說,經常會遇到以下情況:
完全沒有思路 連暴力解都不知道從何下手
知道可以用暴力解 但是更優解想不出來
知道大致的方向(比如需要用到什麼演算法 什麼資料結構之類的)但是完全寫出不來

所以總結一下 就是 演算法瞭解的並不系統(東一腳西一腳 記不住 需要檢索的時候沒有方向) 還有就是不熟練
所以本文的主要方向是系統的整理一下解題思路,當然 這些思路不一定用於解演算法題 對於生活中的一些事也是很有幫助。

首先說演算法題目的思路分類,這分類實在太多了
比如說:用演算法解/資料結構解,用遍歷解/遞迴解, 用complete search解/Greedy解 等等等等。

如果分解一道題目的解答來看的話:程式碼由以下部分組成:
corner case + 初始化 + 核心程式碼
三者一樣重要 任何一個出問題都解決不了問題。

我們先按照演算法題目的分類來說:
演算法解:這演算法太多了 比如各種字串演算法,DP,greedy, binary search等等
資料結構解:這種如果做的多了 看到一個東西容易就知道用什麼資料結構解,比如sum range的線段樹和樹狀陣列,queue/stack解決其他一些問題。而且還有最特殊的一類就是linkedlist,技巧特別多,比如奇偶複製,反向讀取,環的判斷,環的起始點,雙連交替合併等等,這些技巧都是要常常refresh的,而且與linkedlist類似,樹也是這樣。Design的題目 也要求我們

因為演算法的型別實在事太多了 所以我們先從資料結構說起 詳細的遍歷各種演算法體重常用的資料結構。
(注意這裡所說的資料結構是我們常用來解題的 不是常見的 所以沒有包括linkedlist和樹/圖)
首先 array arraylist linkedlist自然不必多說
此外 常用的有:
FIFO/FILO(4): Queue, PQ, Heap, Stack (queue和stack都是使用linkedList實現 PQ有自己的實現方式)
Map/Set(2+2): HashMap/HashSet/TreeMap, TreeSet
特殊型別的樹狀資料結構(3):Trie, Segment Tree, Binary Index Tree
並查集(1):Union find
數了數一共十二種。

那麼演算法大致有哪些呢?
針對不同型別的問題有不同的演算法:
字串:各種字串匹配演算法
字串/陣列:雙指標(單向雙指標 雙向雙指標)排序 滑動視窗
樹:pre/in/post/level order(本質也是BFS/DFS)以及其的各種變形用以滿足要求,而且必須知道何時適合用遞迴
圖:DFS/BFS(又可以細分成拓撲排序等等)
並不針對固定型別題目的演算法: Backtracking, DP, Greedy, 排序,line sweep, reservoir sampling.
其中,我們可以把暴力解法,backtracking,DP with剪枝,DFS, BFS看作是complete search因為他們都是的出來所有的可能的結果然後選擇合適的。其他的比如貪心演算法就屬於“投機取巧” 當然這還要看題目的具體要求 看題目是輸出所有 還是輸出1個(哪怕存在多個) 還是輸出符合條件的n個
這部分太難總結了 因為實在是沒辦法總結,只有:
雙指標 排序 滑動視窗 貪心演算法 動態規劃 還算是典型的好總結一些 接下來會分專題進行總結

所以總的來說 應該用什麼思路去想一個從來沒見過的題目呢?
首先定義一下這個問題:輸入是什麼 輸出是什麼 屬於什麼型別的問題(字串?陣列?Math?樹?圖?)想一想每個要注意什麼問題 有什麼被常用的資料結構?有什麼常用的演算法?
如果毫無頭緒 可以把資料結構過一遍 想像有沒有非常適合這道題目的(這很考驗經驗)
然後過一遍有哪些演算法(技巧)【這個很不現實 因為既沒有那麼多時間 也沒有辦法想到所有的演算法】
如果還是啥都沒有 想一下暴力解法 然後開始寫 剛開始不要擔心時間和空間複雜度的問題 那怕用的自己都不好意思了 只要能做出來就行。
然後就是熟練程度和follow up優化了 這個太考驗功力了 總結性的東西就只能幫到這裡了

相關文章