第九章 动态规划
343.整数拆分
dp[i]
表示拆分i
得到的最大乘积,对于[1,i)
范围内的任意数j
,dp[i]
最大,即max(j与(i-j)乘积, j与(i-j)最大拆分结果
dp[i-j])
边界情况:对于一个正整数将其拆分为至少两个正整数之和,dp[0],dp[1]没有意义
在遍历过程中当j>i/2
时,相当于重复前面的遍历过程,所以j取[1,i/2]
,记录遍历过程中第i轮的最大值dp[i]
func integerBreak(n int) int {
dp := make([]int, n+1)
for i := 2; i <= n; i++ {
for j := 1; j <= i/2; j++ {
dp[i] = max(dp[i], j*(i-j), j*dp[i-j])
}
}
return dp[n]
}
96.不同的二叉搜索树
对于一棵二叉搜索树,左子树小于右子树,因此,遍历1到n范围内的任意数字i,将其作为根节点,递归构建左子树[1,i-1]
与右子树[i+1,n]
dp[i]
表示以i为根节
点构建BST树的所有情况
边界情况:空节点或只有一个根节点只有一种情况,dp[0] = 1,dp[1] = 1
func numTrees(n int) int {
dp := make([]int, n+1)
dp[0], dp[1] = 1, 1
for i := 2; i <= n; i++ {
for j := 1; j <= i; j++ {
dp[i] += dp[j-1] * dp[i-j]
}
}
return dp[n]
}
递归:超时了!!!
func numTrees(n int) int {
if n == 0 || n == 1 {
return 1
}
res := 0
for i := 1; i <= n; i++ {
leftres := numTrees(i - 1)
rightres := numTrees(n - i)
res += leftres * rightres
}
return res
}