题目1:343 整数拆分
题目链接:343 整数拆分
题意
将正整数n拆成k个正整数的和(k>=2)使整数的乘积最大化
尽量拆成若干个数值近似相等的数,这使用的是数学里面的思想:ab<=(a^2+b^2)/2 (当且仅当a=b时,ab乘积取最大值)
动态规划
动规五部曲:
1)dp数组及下标i的含义
dp[i] 对数值i进行拆分,得到的最大的乘积是dp[i]
2)递推公式
dp[i] = max(j*(i-j),j*dp[i-j],dp[i])
自身,拆成两项,拆成3项及以上
3)dp数组初始化
dp[0] 没有意义 dp[0] = 0
dp[1]没有意义 dp[1] = 0
dp[2] = 1
4)遍历顺序
i从3开始遍历 从3开始拆
for(i=3;i<=n;i++)
for(j=1;j<=i/2;j++)//使用j拆分i
5)打印dp数组
代码
class Solution {
public:int integerBreak(int n) {//定义dp数组 vector<int> dp(n+1, 0);//dp数组初始化dp[0] = 0; //无意义dp[1] = 0; //无意义dp[2] = 1;//遍历顺序//从3开始拆分for(int i=3;i<=n;i++){for(int j=1;j<=i/2;j++)//使用j拆分i{dp[i] = max(dp[i],max(j*(i-j),j*dp[i-j]));//自己,拆成两项,拆成3项及以上}}return dp[n];}
};
- 时间复杂度:O(n^2)
- 空间复杂度:O(n)
题目2:96 不同的二叉搜索树
题目链接:96 不同的二叉搜索树
题意
由n个节点组成的的节点值从1到n互不相同的二叉搜索树的种类
首先确定二叉搜索树的性质,二叉搜索树就是一个有序数组,
可以组成最简单的二叉搜索树
动态规划
动规五部曲:
1)dp数组及下标i的含义
dp[i] : 1~i为节点(i个节点)可以组成dp[i]种不同的二叉搜索树
2)递推公式
dp[i] += dp[j-1]*dp[i-j]
代表以j为头节点,那么左子树一定有j-1个元素(因为元素是1-n),右子树有i-(j-1)-1(注意要减去头节点) 将1-n个元素各为头节点都遍历一遍,然后将这些情况累加起来
3)dp数组初始化
dp[0] = 1 左右子树有空的情况,符合二叉搜索树的定义
4)遍历顺序
根据递推公式,i的状态由i-1的状态推导,所以从小到大遍历
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++){
}
5)打印dp数组
代码
class Solution {
public:int numTrees(int n) {//定义dp数组vector<int> dp(n+1,0);//初始化dp数组dp[0] = 1;//遍历for(int i=1;i<=n;i++){for(int j=1;j<=i;j++)//以i为头节点的二叉搜索树的个数,左子树从j-1开始一直到i-1变化{dp[i] += dp[j-1]*dp[i-j];}}return dp[n];}
};
- 时间复杂度:O(n^2)
- 空间复杂度:O(n)