第二期的動態規劃來啦!
題目如下:
給出某乙個陣列,在給出乙個數字s,需要判斷陣列中是否存在乙個或幾個數之和等於這個sum,如果存在,則輸出true,如果不存在,則輸出false。
樣例:輸入
3 34 4 12 5 2
輸出true
這次還是分為遞迴與非遞迴來解題,先是遞迴方法。
我們一樣還是可以用選和不選的思路。還是從最後乙個數字2看起,如果我們選了這個2,那麼我們就要從剩下的數字中組合出數字7才行,而我們如果不選數字2的話,那麼我們就要從剩下的數字組合出9才可以。由此,我們可以得到乙個遞迴的式子(設這個遞迴函式為subset(int arr, int idx, int sum)):
選:subset(arr, idx-1, sum-arr[idx]);
不選:subset(arr, idx-1, sum);
上面我們已經得到了遞迴式,然後就是找遞迴出口。
這題的遞迴出口應該也不算難找。首先是當sum=0的時候,表示已經得到了一種等於sum的組合,那麼我們返回的就是true。第二個是當sum!=0並且已經找到陣列的邊界的時候(即idx=0時),那麼我們就要比較arr[0]與sum是否相等,相等為true,不相等為false。第三個就是如果碰到arr[idx]>sum的時候,此時我們就只要走不選的那條分支就好。(這個出口個人認為算是剪枝,因為就算不寫好像對答案也不會有什麼影響,如果有錯請大佬們指出。)這樣我們就得到了所有的遞迴條件,、
附上**:
public class test ;
int sum = 9;
system.out.println(subset(arr, arr.length-1, sum));
}public static boolean subset(int arr, int idx, int sum)
if (idx == 0)
if (arr[idx] > sum)
return (subset(arr, idx-1, sum-arr[idx]) || subset(arr, idx-1, sum));
}}
接下來是非遞迴方法。這道題我們需要開乙個二位陣列dp來儲存,陣列的行號表示arr陣列的下標,陣列的列號表示從0-sum的數值。根據遞迴的出口,我們還需要把這個陣列的第一行和第一列填好。第一行表示的是遞迴中我們已經搜尋到了陣列的邊界,那麼此時的arr[0]是否與sum相等。第一列表示的是當sum為0時,當然,sum為0表示已經找到了某種組合,那麼第一列的值當然都為true(dp[0][0]不管是為true還是false,我暫時還沒有發現對結果會產生影響。)。再接下來我們就是根據遞迴式來填寫剩下的資料。由於是二位陣列,所以我們需要用乙個巢狀的for迴圈來填資料。根據乙個剪枝的式子,和另乙個遞迴式子我們不難得到dp關係。
下面附上**:
public class test ;
int sum = 9;
system.out.println(dp(arr, sum)[arr.length-1][sum]);
}public static boolean dp(int arr, int sum)
for (int i=1; ij) else}}
return dp_arr;
}}
Leetcode 02動態規劃
ac 72.編輯距離 198.打家劫舍 213.打家劫舍 ii 516.最長回文子串行 674.最長連續遞增序列 題目鏈結 class solution return result bool ispalindrome string s return true 判斷完是回文串 參考解答 class s...
LeetCode分類02 動態規劃
動態規劃常適用於有重疊子問題和最優子結構性質的問題,它的本質是以空間換取時間。它的模板步驟如下 按上述步驟進行詳細敘述 思考狀態 狀態的定義,先試著將題目所求的設定為狀態 然後思考狀態是如何轉移的,如果狀態轉移方程不易得到,嘗試修改定義,目的依然是為了方面得到狀態轉移方程。思考狀態轉移方程 思考初始...
Task02 動態規劃
1.最長回文子串 class solution def longestpalindrome self,s str str n len s dp false n for in range n ans 列舉子串的長度 l 1 for l in range n 列舉子串的起始位置 i,這樣可以通過 j i...