所有的演算法題第一要義就是要明白題目講什麼,明白規律是什麼,只有知道了規律才能寫**,才能輪到使用什麼方法,什麼工具,是用遞迴?還是迴圈?進而才能用到你總結的各種經驗。
下面的題目除了動態規劃,其他主要來自劍指offer的題目,而且主要是資料結構題 ,排序演算法我們單獨整理。
1、遞迴模板以及使用技巧總結:
2、思路總結:遞迴我們知道本質是重複做同一件事,經常的我們能夠想明白這個事是怎麼樣的,但是卻難以下手,為什麼?因為如果從最開始的情況去思考,會很難理解,比如歸併排序,一直二分下去,到最後只有乙個元素,這怎麼對比?怎麼體現在**上?容易思考得走火入魔。這個時候,我們可以直接把他當作中間的時候來寫**,這樣十分容易。比如015迴圈演算法,和歸併排序(特別是歸併)就是個例子。
3、說一下時間複雜度:1 < o(logn) 4、斐波那契數列使用的遞迴的複雜度是o(2^n),因為它可以看作乙個顆二叉樹,二叉樹的高度是 n - 1,由我們的基礎知識可以知道,乙個高度為k的二叉樹最多可以由 2^k - 1個葉子節點,也就是遞迴過程函式呼叫的次數,所以時間複雜度為 o(2^n),而空間複雜度就是樹的高度 s(n)
鍊錶題主要方法就是兩個指標和遞迴和迴圈,我們先從這三個角度去思考。
} 二叉樹的題幾乎就是遞迴,因為有左右子樹沒法迴圈,只能遞迴
為了快速學習,我參考了動態規劃 這位的動態規劃思路,這樣上手快一點。
動態規劃的核心思想是:數學歸納法。有點忘記了什麼是數序歸納法,舉個例子你就知道了:
證明:s(n) = 1 + 2 + 3 …. + n 前n項和為n(n + 1) / 2
n = 1, s(1) = 1
假設n時命題成立 ----------假設某個時候成立,證明他後面的是否也成立
n+ 1時,
s(n + 1)
= s(n) + n + 1
= n(n + 1)/2 + n + 1
= (n + 1)(n + 2)/ 2
因此成立
為什麼會想到他是動態規劃呢?emm,我還沒搞明白,就目前我們掌握的,遞迴,迴圈,二分似乎都用不上,那麼就只剩下動態規劃?暫時先這麼想吧。
第一步:動態規劃一定有乙個陣列dp,我們首先就要想好這個陣列表達什麼意思,其實很明顯,這個陣列應該是:dp[5] 表示num[5] 他的最長上公升序列長度是多少?因此我們的最終返回結果應該是:
for
(int i =
0; i < dp.length; i++
)
第二步:dp[5]這個值怎麼算的呢?這當然才是關鍵,而你的思考應該是dp[5]怎麼通過dp[0]----dp[4]的來的到dp[5]。很明顯的其實應該是index = 5這個前面第乙個小於他的index 對應的dp[index] + 1 就是 dp[5] 的值。當然了這裡他用的從頭開始比較:–我要試驗一下我的方法,當然不影響複雜度其實。但是他這個思想我認為是最樸素的,最暴力的,我覺得一開始可以按他這麼來想。其次這個模式: dp[i] = math.max(dp[i], dp[j] + 1); 也是常用模式。
for
(int j =
0; j < i; j++
)
更進一步的,所有dp[n]都可以寫出來:
for
(int i =
0; i < nums.length; i++
)}
第三步:細節dp[n]應該要初始化大小為1,這個初始化也是動態規劃必須的動作。
驗證一下我的想法,也就是從n-1開始比較,不要再從頭比較了:這樣是正確的,當然其實複雜度不會變。
for
(int j = n-
1; j >=
0; j--
)}
能裝的價值是多少?
也是三步走
1、構建陣列,這裡明顯有兩個狀態因此就是大膽的給他定為二維陣列:dp
;但是關鍵還是要定義出這個二維陣列是表示什麼含義,應該是dp[i][w] = val
表示:前i個物品,在揹包容量為w的時候,最多放價值val。總結:我們可以看到dp陣列的值一定是我們最後要的東西,比如最長序列是序列長度,硬幣問題是硬幣數量。其次就有兩個遍歷for。
2、分解子問題,已知xx,求dp[i][w]
。思考的方向其實和硬幣的一樣,就是w-遍歷物品的重量,然後就是前乙個val+減去遍歷物品的val,表示式是:dp[i][w] = dp[i-1][w-weight[i-1]] + val(i)
。然後他有個選擇問題,就是要不要把第i個物品放進去,如果不放那麼就是dp[i-1][w]
。綜合到**就是:
// w是要求小於的重量 n是幾個物品
public
static
intmethod
(int w,
int n,
int[
] wt,
int[
] val)
else}}
return dp[n]
[w];
}
3、資料初始化,其實應該是第一行和第一列為0,但是陣列已經幫忙我們全部定義為0 演算法刷題小總結
1.有問題 class solution if i 0 reverse nums.begin nums.end else swap nums k nums i sort nums.begin k 1 nums.end 問題 這種while 裡面加了個if else判斷的話,如果處於邊界時,else ...
演算法筆記 刷題2 5
b 習題6 5 陣列元素逆置 c 習題6 6 楊輝三角 d 習題6 12 解密 e 習題6 13 字串比較 f 例題6 1 逆序輸出陣列元素 b 習題6 5 陣列元素逆置 g 例題6 2 陣列求解fibonacci數列問題 h 例題6 3 氣泡排序 i 例題6 4 矩陣轉置 j 例題6 9 字串求最...
演算法筆記 刷題2 6
b 習題7 7 複製字串中的母音字母 寫乙個函式將乙個字串按反序存放。在主函式中輸入乙個字串,通過呼叫該函式,得到該字串按反序存放後的字串,並輸出。一行字串。輸入字串反序存放後的字串。單獨佔一行。abcddcbastrlen s1 計算s1字串內的字元數 包括 0 include include i...