第九章 动态规划part03

46 阅读1分钟

343. Integer Break

Given an integer n, break it into the sum of k positive integers, where k >= 2, and maximize the product of those integers.

Return the maximum product you can get.

题目解析:

  • 可以使用回溯或者dp解决
  • 需要比较两种情况
    • dp[i] = Math.max(dp[i], dp[i-j]*j)
    • dp[i] = Math.max(dp[i], (i-j) * j)

代码:

    public int integerBreak(int n) {
        if (n == 2) return 1;
        int[] dp = new int[n+1];
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= i-j; j++) {
                dp[i] = Math.max(dp[i], j * (i - j));
                dp[i] = Math.max(dp[i], dp[i - j] * j);
            }
        }
        return dp[n];
    }
}

96. Unique Binary Search Trees

Given an integer n, return the number of structurally unique BST' s (binary search trees) which has exactly n nodes of unique values from 1 to n.

题目解析:

  • 可以使用递归算出能够构造二叉树的个数,
  • 上面方法存在重复计算,所以可以使用数组存放计算后的值,避免重复计算

代码:
1. 递归

class Solution {
    public int numTrees(int n) {
        if (n == 1) return 1;
        int num = 0;
        for (int i = 1; i <= n; i++) {
            int left = 1, right = 1;
            if (i > 1) {
                left = numTrees(i - 1);
            }
            if (i < n) {
                right = numTrees(n - i);
            }
            num += left * right;
        }
        return num;
    }
}

2. Memoization

class Solution {
    
    public int numTrees(int n) {
        int[] dp = new int[n+1];
        dp[1] = 1;
        dfs(n, dp);
        return dp[n];
    }

    public int dfs(int n, int[] dp) {
        if (dp[n] == 0) {
            for (int i = 1; i <= n; i++) {
                int left = 1, right = 1;
                if (i > 1) {
                    left = dfs(i - 1, dp);
                }
                if (i < n) {
                    right = dfs(n - i, dp);
                }
                dp[n] += left * right;
            }
        }
        return dp[n];
    }
}

3. DP

class Solution {
    
    public int numTrees(int n) {
        int[] dp = new int[n+1];
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= i; j++) {
                dp[i] += dp[j - 1] * dp[i - j];
            }
        }
        return dp[n];
    }

}