LeetCode 343 整數拆分
阿新 • • 發佈:2020-07-30
LeetCode 343 整數拆分
給定一個正整數,將其拆分為至少2個正整數之和,求出拆分後所有數的最大乘積
- 遞迴(暴力),對於數n,每次將其拆分為兩個數:curr(本次拆分值)、rem(剩餘值),並遞迴呼叫對rem繼續拆分直到為0、1
- 記憶化遞迴,將對每次rem的最優拆分結果進行儲存,避免重複計算
class Solution_LC_343 { public int integerBreak(int n) { //記憶陣列 int[] memo = new int[n]; int ans = 0; //i表示第一個拆分值,該值必須小於n,因此不放在遞迴中 for(int i=1; i<n; i++) { int tmp = integerBreak(n-i, i, memo); ans = (ans>tmp)? ans:tmp; } return ans; } //記憶化遞迴,memo[]儲存每個數rem的最優解 (0< rem < n) public int integerBreak(int rem, int curr, int memo[]) { //剩餘拆分值為0,1不需要繼續向下拆分 if(rem==0 || rem==1) { return curr; } int result = 0; if(memo[rem]==0) { for(int i=1; i<=rem; i++) { int tmp = integerBreak(rem-i, i, memo); result = (result>tmp)? result:tmp; } } else { result = memo[rem]; } return curr*result; } }
- 動態規劃(優化)
class Solution_LC_343 { public int integerBreak(int n) { //dp[i]表示對i進行拆分後得到的最優解 int[] dp = new int[n + 1]; for (int i = 2; i <= n; i++) { int curMax = 0; for (int j = 1; j < i; j++) { //比較對剩餘拆分之(i-j)不進行拆分、進行拆分兩種結果 curMax = Math.max(curMax, Math.max(j * (i - j), j * dp[i - j])); } dp[i] = curMax; } return dp[n]; } }