343. 整数拆分
思路:
数值相近的数字相乘才有可能形成最大乘积。对于每一个i,用j表示分离出的数(只需到达i/2),第一个max用来更新dp[i]取最大值,里面的max用来表示取2数或2数以上相乘的最大值。
代码:
class Solution {
public int integerBreak(int n) {
//dp数组含义:dp[i]表示拆分i得到的最大乘积
int[] dp = new int[n + 1];
dp[2] = 1;
for(int i = 3; i <= n; i++){
//从i中挨个数拆出来试
for(int j = 1; j <= i/2; j++){
dp[i] = Math.max(dp[i], Math.max(j*(i - j), j*dp[i - j]));
}
}
return dp[n];
}
}
需要注意的点:
1、只初始化dp[2]=1即可。
2、j不用遍历到i终止,数值相近的数字相乘才有可能形成最大乘积。
96.不同的二叉搜索树
思路:
n个节点的二叉搜索树数量要从1为头结点的数量一直累加到n,随着不同头结点变化,其左(右)树节点数也会变化。每一种数字为头结点的二叉搜索树数量=左树摆法(小于当前数)*右树摆法(大于当前数),左树可以从0开始一直到i-1.
代码:
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++){
//j代表左树节点数,,dp[j]表示左树,dp[i - j - 1]表示右树
for(int j = 0; j <= i - 1; j++){
dp[i] += dp[j] * dp[i - j - 1];
}
}
return dp[n];
}
}
需要注意的点:
1、初始化dp[0]=1,表示左(右)树为空的一种摆法。