动态规划问题需要找到后一个问题关联的前一个或前几个子问题,在整数拆分问题中,后一个整数的拆分由前面整数的拆分决定。在不同二叉搜索树问题中,拆分一个二叉树,依赖于当前的根节点可以拆分出多少搜索二叉树。
343. 整数拆分
动归五部曲:
- dp[i]:i被拆分的最大乘积
- dp数组初始化:
- 遍历方式:
- 递归函数:dp[i] = max(dp[i],max(j*(i-j),j*dp[i-j]))
- 打印dp数组
class Solution:
def integerBreak(self, n: int) -> int:
# 原则:拆分一个数n 使之乘积最大,那么一定是拆分成m个近似相同的子数相乘才是最大的
# dp算法的五步曲:dp数组的初始化,递推公式,dp数组下标的含义
dp = [0] * (n+1)
dp[0] = 1
dp[1] = 1
dp[2] = 1
for i in range(3,n+1):
for j in range(1,i):
dp[i] = max(dp[i],max(j*(i-j), j*dp[i-j]))
print(dp)
return dp[n]
96.不同的二叉搜索树
- dp[i]: 1到i为节点组成的二叉搜索树的个数为dp[i]。
- 递推公式: dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]
本题与前几道题目不太一致的地方在于,本题在递归函数的选取上更加复杂,需要乘积和累加的形式。
- dp数组初始化:dp[0]=1
- 遍历顺序从前往后
- 打印dp数组进行测试
class Solution:
def numTrees(self, n: int) -> int:
dp = [0]*(n+1)
dp[0] = 1
for i in range(1,n+1):
for j in range(1,i+1):
dp[i] += dp[j-1] * dp[i-j]
print(dp)
return dp[n]