個人演算法 資料結構複習筆記

2021-10-10 16:04:31 字數 3039 閱讀 9212

github專案位址

直觀地想,乙個演算法的執行時間也就是執行所有程式語句的耗時總和。然而在實際的分析中,我們並不需要考慮所有程式語句的執行時間,我們應該做的是集中注意力於最耗時的部分,也就是執行頻率最高而且最耗時的操作。

但是對於遞迴、或各分支條件不確定的演算法較難分析。

詳細介紹見:遞迴演算法時間複雜度分析

十大經典排序演算法

貪心演算法原理:找到最優子結構,並證明正確性。

for(int i=1;i}
刻畫乙個最優解的結構特徵。

遞迴地定義最優解的值。

計算最優解的值,通常採用自底向上的方法。

利用計算出的資訊構造乙個最優解。

對於確定狀態轉移方程就在第一步和第二步中,首先要確定問題的決策物件,接著對決策物件劃分階段並確定各個階段的狀態變數,最後建立各階段的狀態變數的轉移方程。

例如用dp[i]表示以序列中第i個數字結尾的最長遞增子串行長度和最長公共子串行中用dp[i][j]表示的兩個字串中前 i、 j 個字元的最長公共子串行,我們就是通過對這兩個數字量的不斷求解最終得到答案的。這個數字量就被我們稱為狀態。狀態是描述問題當前狀況的乙個數字量。首先,它是數字的,是可以被抽象出來儲存在記憶體中的。其次,它可以完全的表示乙個狀態的特徵,而不需要其他任何的輔助資訊。最後,也是狀態最重要的特點,狀態間的轉移完全依賴於各個狀態本身,如最長遞增子串行中,dp[x]的值由 dp[i](i < x)的值確定。若我們在分析動態規劃問題的時候能夠找到這樣乙個符合以上所有條件的狀態,那麼多半這個問題是可以被正確解出的。所以說,解動態規劃問題的關鍵,就是尋找乙個好的狀態。

對於一部分動態規劃題目,直觀的狀態往往涉及多個維數,這些狀態在一定條件下可以進行狀態壓縮。鏈結

一般來說,如果dp[i][j]的轉移只與二維陣列本行的上一行有關(如dp[i][j]=dp[i-1][j-1]+dp[i-1][j-2],斐波那契)。則可壓縮第一維。

查詢旋轉排序陣列:二叉樹相關經典遞迴思路:判定當前點,遞迴呼叫左子樹,遞迴呼叫右子樹。例如,對有序數列生成高度平衡的二叉搜尋樹,每次取陣列中點,中–左--右進行處理。有些題目用遞迴思路難度不會減小例如通過前序陣列和中序陣列構建二叉樹。

根據前序、中序序列構造二叉樹:遞迴思路:記錄前序數列左右點,記錄中序數列當前點(根節點),根據根節點,和子樹範圍,構建根節點的左右子樹。迭代思路:用棧儲存沒有構建右子樹的節點,對於前序序列順序遍歷,中序數列記錄當前位置。向左新增節點(同時加入棧)直到棧頂節點值等於中序數列當前位置,相當於到達了左側底部。此時出棧,中序數列記錄向前移動一格,直到棧頂節點值不等於中序數列當前位置,並將當前前序序列值加入右節點,將右節點入棧。建議用影象模擬。

二叉樹中最大路徑和:路徑被定義為一條從樹中任意節點出發,沿父節點-子節點連線,達到任意節點的序列,其中最底部的父節點可以包含兩個子節點。採用遞迴的思路,遞迴呼叫乙個點能貢獻的最大值,同時全域性儲存乙個最大路徑的答案。

轉殖圖:在記憶體中完全拷貝乙個圖,圖的每乙個node包含對應的值和相鄰節點的陣列。通過map儲存新圖和舊圖節點的對應關係,如果當前節點為map中存在的節點,說明這個節點已經建立過,直接返回map對應的引用。反之則新建節點,遍歷當前節點(舊圖)的鄰接節點陣列,對於每乙個節點遞迴呼叫建立程式。

組合總和使用多次:給定乙個無重複元素的陣列 candidates 和乙個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。其中每個數字可以使用多次。總體使用dfs的思路,對candidate陣列進行遍歷,當前值大於target則跳過,當前值等於target則返回含有當前值的list,當前值小於target,則遞迴呼叫target-當前值。優化方案:記錄位置,每次遞迴從位置p開始遍歷。

組合總和使用一次:首先對陣列進行排序,每次小於target時,用while確認有n個重複值,進行n次迴圈,每次加入1,2,3,…,n個當前值,p設定為i+n,並對當前遍歷的i設定為i+ n

按層遍歷二叉樹:使用佇列儲存樹中待訪問的節點,每層迴圈當前佇列中節點的次數,迴圈中每次從佇列移出乙個節點,並加入這一節點的左右子節點。

單詞接龍:給定兩個單詞(beginword 和 endword)和乙個字典,找到從beginword 到endword 的最短轉換序列的長度。轉換需遵循如下規則:每次轉換只能改變乙個字母。轉換過程中的中間單詞必須是字典中的單詞。bfs的解空間形如[hot–hit–hip–tip].bfs的思路為儲存乙個佇列,代表待遍歷的單詞,每層迴圈當前佇列中單詞的數量,迴圈中每次從佇列移出乙個單詞,並加入這一單詞的所有合法接龍詞。層數加一,如果加入的詞有目標詞,則返回當前層數+1。優化bfs是使用boolean陣列儲存訪問過的節點,訪問過就不要加入佇列了(其實是貪心,先加入就的層數一定比後加入的小)。

單詞接龍-雙向bfs:維持兩個佇列和visited,從開始單詞和結束單詞分別開始bfs,誰的佇列短就先執行誰,每執行一層(不管是誰),層數+1,當遍歷到被另乙個方向訪問過的節點,返回層數+1.

回溯法 採用試錯的思想,它嘗試分步的去解決乙個問題。在分步解決問題的過程中,當它通過嘗試發現現有的分步答案不能得到有效的正確的解答的時候,它將取消上一步甚至是上幾步的計算,再通過其它的可能的分步解答再次嘗試尋找問題的答案。回溯法通常用最簡單的遞迴方法來實現,在反覆重複上述的步驟後可能出現兩種情況:

找到乙個可能存在的正確的答案;

在嘗試了所有可能的分步方法後宣告該問題沒有答案。

回溯是一種更通用的演算法。可以用於任何型別的結構,其中可以消除域的部分 ——無論它是否是邏輯樹。深度優先搜尋是與搜尋樹或圖結構相關的特定回溯形式。它使用回溯作為其使用樹的方法的一部分,但僅限於樹/圖結構。

全排列:每次遞迴維持乙個output陣列,遍歷每次負責output i位置的所有情況,及i位置當前數字和j位置交換之後,遞迴i處理之後的output,每當i==陣列長度的時候,將當前output存入答案集。遞迴呼叫之後,要恢復i和j位置交換的數字,以遍進一步遍歷i和j+1位置互換。

演算法資料結構筆記 列舉

列舉就是猜測每一種可能性,比如1 3,如果不用代數計算的話,那麼就把0 9都嘗試一遍,即可得出答案。考慮這樣的乙個問題,51 空格中,數字隨意填寫,可重複,不考慮0。我們通過四層for迴圈,分別遍歷1 9暴力列舉所有數字組合可能性,來得出答案。include include include int ...

演算法(資料結構)

空間不夠儲存 給40億個不重複的unsigned int的整數,沒排過序的,然後再給乙個數,如何快速判斷這個數是否在那40億個數當中 40億個數空間儲存的問題 利用對映 分析 unsigned 範圍是2 32 40億大約大約4g個數不到,常規方法肯定是不行的 我們你可以利用 伴隨陣列 那種思想利用記...

演算法 資料結構

演算法是程式的核心,演算法的好壞直接決定了程式的好壞 基礎的幾種演算法 二分查詢 氣泡排序 插入排序 選擇排序 快速排序 二分查詢 假設資料是按公升序排序的,對於給定值x,從序列的中間位置開始比較,如果當前位置值等於x,則查詢成功 若x小於當前位置值,則在數列的前半段中查詢 若x大於當前位置值則在數...