力扣labuladong一刷day72天动态规划
文章目录
- 力扣labuladong一刷day72天动态规划
- 一、343. 整数拆分
- 二、96.不同的二叉搜索树
一、343. 整数拆分
题目链接:https://leetcode.cn/problems/integer-break/description/
思路:本题为整数拆分,可以拆分为k个数之和,k>1。那么定义dp[i]表示整数i拆分得到的最大和,由此我们可以知道,从2开始都可以被拆分为两数之和,三数之和,等等,对于任意一个i,(i-j)*j是两数之和,dp[i-j]*j就最起码是三数之和了(dp[i-j]的定义就是拆分最大乘积和最起码是拆成两个数),由此可以确定递推公式dp[i]=max( (i-j)*j, dp[i-j]*j )。
class Solution {public int integerBreak(int n) {int[] dp = new int[n+1];dp[1] = 1;dp[2] = 1;for(int i = 3; i <= n; i++) {for(int j = 1; j <= i/2; j++) {dp[i] = Math.max(dp[i], Math.max((i-j)*j, dp[i-j]*j));}}return dp[n];}
}
二、96.不同的二叉搜索树
题目链接:https://leetcode.cn/problems/unique-binary-search-trees/description/
思路:求不同的二叉搜索树的种类,本质还是遍历穷举,任意一个树的种类等于他左子树的种类乘以右子树的种类,只不过左右子树的数量需要遍历,定义dp[0]=1,故递推公式为dp[i] += dp[j] * dp[i-j-1];
class Solution {public int numTrees(int n) {if(n < 3) return n;int[] dp = new int[n+1];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-j-1];}}return dp[n];}
}