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

题目链接:343. 整数拆分

1.代码

暴力做法:n前进行组合搜索得出二维数组result存放结果,然后对里面的元素进行乘积,谁最大就是结果

2.递归做法

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

2.递归五部曲

1.推导dp数组和其中的含义

题目为求拆分n的乘积最大值,这就是dp数组的含义

2.推导递推公式

f[i]等于什么呢?由题目可以看出,我们先来看后面几个,因为题目没有说,我们不知道前几步到底在哪,k必须大于或等于2,我们就可以看成f[i]是由2个,3个,4个,i个构成的,我们可以先定义一个变量j遍历,确定第一个元素

如果是2个时,f[i] = j *(i - j)

如果是更多个,f[i] = j * f[i - j];

所以我们可以确定这两种类型可以确定f[i]

因为是对j进行for循环,我们需要对每个j求,最后的最大值就是结果

f[i] = max(f[i], max(j * (i - j), j * f[i - j]))

3.确定初始参数值

我们可以确定必须要分成两份,f[2] = 1

4.确定递推顺序

因为我们需要求f[n],所以最外面一层是对每个i进行求最大值,直到求到n

第二层就是对每个i求最大值的逻辑,确定第一个参数,其他参数就能够确定了

5.举例推导dp数组

可以自己模拟前面几个看一看正确不正确


题目链接:96. 不同的二叉搜索树

1.代码

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

 2.递归五部曲

1.确定dp数组和其下标含义

题目求结点数位n的二叉搜索树的个数,dp[i]就是求结点数位i的搜索树个数

2.确定递推公式

怎么求出的二叉搜索树的个数呢?

如3,对每个结点都有是根节点的可能性,根节点可以是1,2,3。当结点为1时,左子树必须比1小,说明左子树个数为0,右子树为2.  当结点为2时,左右子树各一个结点。  当根结点为3时,左边有两个,右边没有,可以推导f[3] = f[0]f[2] + f[1][1] + f[2][0],就是i为根,比i小的个数*比i大的个数就是以i为根节点的二叉搜索树个数

f[i]:i个结点搜索树的个数,--求出f[i]必须求出从1到i为根结点的二叉搜索树的个数和

3.初始化

介于推导地推公式需要f[0]=1,为0不能,f[1]=1,f[2] =2,其实可以不写这么多,用到哪个写哪个

4.确定递推顺序

因为需要求出f[n]前必须求出f[1-n]所以外面一层循环是求每一个f[i],里面的循环是有i个结点后以j为根结点的个数,对其求和就是i个结点的二叉搜索树的个数了

5.距离说明dp数组

 

可以自己距离前面几个模拟一下

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值