1. 程式人生 > >常用演算法(二)

常用演算法(二)

續 常用演算法(一)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

五,動態規劃

適用條件

  • 問題的解可由子問題的解組合而成;
  • 子問題有重疊,會被重複求解;
  • 無後效性。某階段的狀態一旦確定,則此後過程的演變不再受此前各種狀態及決策的影響。例如鋼條切割問題。當n=3的最佳方案求出之後,計算n=4時的最佳方案時不會再影響到n=3的最佳方案的結果了。又例如最大子陣列的和問題,當P[i]求出之後,在計算P[i+1]時,不會改變P[i]的值。
  • 經常用於求最優解,或求完成某種任務的方法個數

解題步驟

  1. 求出遞推式(求遞推式可以採用自頂向下的選擇法,也可採用自底向上的遞推法。)
    • 選擇法(推薦,更直觀):主問題上做一個選擇,問題變化成一個或多個子問題。常用於問題能夠被化為多個子問題的情況:如干活(連續兩天干活後必須休息一天)。又如best time to buy and sell a stock IV
    • 遞推法:假設子問題已經被解決,主問題在子問題的基礎上如何解:常用於問題能夠被化為一個子問題的情況。(最大子陣列的和)
  2. 第二步:自底向上,用一個數組儲存子問題的求解結果。或自頂向下,用cache儲存結果 

動態規劃的變形

有些問題難以做到直接使用動態規劃求解,需要一個轉換。例如最大子陣列的和問題。如果希望直接用動態規劃,令P[i]為子陣列0到i的最大子陣列的和,則難以推匯出P[i+1]和P[i]的關係。所以,令P[i]為子陣列0到i的,以i為右邊界的最大子陣列的和,則可以容易推匯出P[i+1]與P[i]的關係。

  • Maximum sub array
  • Longest palindrome string
  • Unique Binary search tree

有些題中,為了求得最終結果,需要規劃多個遞推式。

  • Maximum product subarray 此題以i為右邊界的子陣列的最大乘積需要依賴於以i-1為右邊界的子陣列的最大(正數)和最小乘積(負數)。負數x負數=正數
  • Best time to buy and sell stock IV 兩遞推式:前i天最多允許j次交易的全域性最優解g[i][j]和前i天最多允許j次交易,且最後一次交易發生在第i天的區域性最優解l[i][j]

六,貪心法

適用條件

  • 可用動態規劃解的問題。
  • 尋優問題
  • 當前問題做出一個最優選擇之後,轉化為唯一的一個子問題,然後遞迴求解
  • 動態規劃中,做出的每一個選擇,依賴於子問題的解。貪心則不依賴子問題的解,它只是當前最優的方案。例如Jump Game。如從正向開始求解,令P[i]為從i處到目的地所需要的最少步數,則這是個動態規劃的方案。因為從i出走出的第一步到哪個位置依賴於子問題P[j] ( j是>i且i能到達的所有位置)的值。如從終點反向開始求解,第一步為能到達終點的最遠的一個位置,然後遞迴求解,則是貪心方案,因為當前選擇並未依賴任何子問題的解。事實上,子問題尚未求解。

解題步驟

  自頂向下,用遞迴的方式

前提

  需要證明這個貪心的選擇能夠得到最優解

題例

  • Jump game
  • Meeting room

七,排序應用

全排序

預排序,應用於陣列,和雙指標演算法一起工作
  • Container with most water
  • 2 sum
強制排序,適用於排除重複解
  • Permutation II
  • Subsets II
預排序,可以將o(n2)的演算法降為o(nlogn)
  • Merge Intervals

部分排序

分割,應用於陣列,適用於不需要全部排序,然後需要找到某個位置的場合
  • Find k biggest number
基數排序及其它,適用於時間複雜度要求較高的場合 o(n).
  • Maximum Gap