Day41 | 343. 整数拆分, 96.不同的二叉搜索树

Day41 | 343. 整数拆分, 96.不同的二叉搜索树

重点在于对递推公式的理解,即子状态继承的理解!

整数拆分

LeetCode题目:https://leetcode.cn/problems/integer-break/

整体思路

  按照五步进行分析,dp数组在本题目中的含义为整数n的最大乘积。对于第n个数的最大乘积,存在两种情况,一种是得到一个i值,i ∗ * dp[n-i];另一种情况是dp[i] < < <i,此时i*(n-i)。循环得到的最大值即是所求最大值。

  最后,根据递推公式可以执行正序的遍历。

class Solution {
public:
    int integerBreak(int n) {
        /* 保存第k个数的最大乘积 */
        vector<int> dp(n+1,0);
        dp[0] = 0;
        dp[1] = 0;
        dp[2] = 1;
        for (int i = 3;i <= n;i++) {
            for (int j = 1;j < i;j++ ) {
                dp[i] = max(max(j*dp[i-j],j*(i-j)),dp[i]);
            }
        }
        return dp[n];
    }
};

不同的二叉搜索树

LeetCode题目:https://leetcode.cn/problems/unique-binary-search-trees/

解题思路

  该题主要考察对二叉搜索树的理解。dp数组确定自然是代表n个节点可以构成的二叉搜索树的个数。一个节点和两个节点的情况很容易进行初始化,到三个点的时候情况就开始复杂。可以抽象为,当取最小值的时候,剩下n-1个节点都在右子树,此时考虑左子树0个节点可以构成的个数*右子树n-1个节点可以构成二叉搜索树的个数。

  依次递推,到第i个节点为左子树i-1个节点排列个数 ∗ * 右侧n-1-i个节点排列个数。

  确定遍历方法,由于每个dp的条件应该由之前的子状态确定,因此需要进行正序遍历。

  代码如下:

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

你可能感兴趣的:(数据结构,算法,动态规划,leetcode)