● 343. 整数拆分
● 96.不同的二叉搜索树
动态规划五部曲模板
- dp数组以及下标的含义
- 递推公式
- dp数组如何初始化
- 遍历顺序
- 打印数组
详细布置
今天两题都挺有难度,建议大家思考一下没思路,直接看题解,第一次做,硬想很难想出来。
1. 整数拆分
关联 leetcode 343. 整数拆分
-
思路
- 拆除来的数尽可能都相等
-
dp数组以及下标的含义
dp[i] : 对i进行拆分后,最大的乘积就是 dp[i]
-
递推公式
// 从1遍历j,然后有两种渠道得到dp[i]. dp[i] = j * (i - j) // 是单纯的把整数拆分为两个数相乘 dp[i] = j * dp[i-j] // 拆分成两个以及两个以上的个数相乘 // 递推公式 dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j)
-
dp数组如何初始化
//题目可知: dp[2] = 1
-
遍历顺序
- 从前往后遍历
- i 从3开始遍历
- j 从1开始
-
打印数组
-
题解
func integerBreak(n int) int { dp := make([]int, n+1) dp[2] = 1 for i := 3; i <= n; i++ { // j 走到 i 的一半就行了 for j := 1; j <= i/2; j++ { dp[i] = max(max(dp[i], j*(i-j)), j*dp[i-j]) } } return dp[n] }
2. 不同的二叉搜索树
关联 leetcode 96.不同的二叉搜索树
-
思路
- 二叉搜索树:
- 左边比中间小,右边比中间大
-
dp数组以及下标的含义
dp[i] : 1到i为节点组成的二叉搜索树的个数为dp[i]
-
递推公式
//dp[j-1] : 左边节点数 //dp[i-j] : 右边节点数 dp[i] += dp[j-1] * dp[i-j]// j:=1; j<=i; j++
-
dp数组如何初始化
dp[0],dp[1],dp[2] := 1,1,2// 只用初始化 dp[0]就可以了,后面都可以用递推公式推出来
-
遍历顺序
- 从小到大,从前到后
- 从初始化的方向开始遍历
- 从小到大,从前到后
-
打印数组
- 二叉搜索树:
-
题解
func numTrees(n int) int { if n < 2 { return 1 } dp := make([]int, n+1) dp[0] = 1 for i := 1; i <= n; i++ { for j := 1; j <= i; j++ { dp[i] += dp[j-1] * dp[i-j] } } return dp[n] }