Leetcode 343. Integer Break (python+cpp)

Leetcode 343. Integer Break

  • 题目
  • 解析:
  • 解法1:recursion + memorization
  • 解法2:动态规划

题目

Leetcode 343. Integer Break (python+cpp)_第1张图片

解析:

本质上这道题目和322 coin change是一样的,只不过用自然数替换coin,用max product替换min count而已,这边我们也用两种方法来解

解法1:recursion + memorization

这边的problem和subproblem之间的关系是:

F(s) = max(F(S-i)*i,(S-i)*i for all i)

根据这个式子,很简单的就可以得到解法。
python代码如下:

class Solution:
    def integerBreak(self, n: int) -> int:
        def dfs(remain):
            if remain == 1:
                return 1
            if remain in memo:
                return memo[remain]
            
            memo[remain] = max([(i*max(remain-i,dfs(remain-i))) for i in range(1,remain)])
            
            return memo[remain]
        
        memo = {}
        return dfs(n)

解法2:动态规划

我之前有多次提到过,recursion + memorization就其实等价于动态规划,就是把memo用数组替换,recursion用iteration来替换这样。时间复杂度和空间复杂度也都是O(n)和O(n),根据上面problem和sunproblem的关系,很容易得到状态转移方程:

dp[i] = max(dp[i],dp[i-j]*j,(i-j)*j) for all i and all j<i

python代码如下:

class Solution:
    def integerBreak(self, n: int) -> int:
        dp = [1]*(n+1)
        for i in range(2,n+1):
            for j in range(1,i):
                dp[i] = max(j*dp[i-j],j*(i-j),dp[i])
        return dp[-1]

C++版本如下:

class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n+1,1);
        for (int i=2;i<=n;i++){
            for (int j=1;j<i;j++){
                dp[i] = max(dp[i],max(j*dp[i-j],j*(i-j)));
            }
        }
        return dp[n];
    }
};

你可能感兴趣的:(Leetcode,动态规划)