文章目录
- 前置知识
- 343. 整数拆分
- 题目描述
- 解题思路
- 代码
- 进一步优化
- 96.不同的二叉搜索树
- 题目描述
- 解题思路
- 代码
- 优化改进
- 总结
前置知识
参考前文
参考文章:
LeetCode刷题笔记【29】:动态规划专题-1(斐波那契数、爬楼梯、使用最小花费爬楼梯)
LeetCode刷题笔记【30】:动态规划专题-2(不同路径、不同路径 II)
343. 整数拆分
题目描述
LeetCode链接:https://leetcode.cn/problems/integer-break/description/
解题思路
思路: 动态规划
建立dp
数组, 表示下标i的最大乘积
对每个新的i
, 将i
分成(i=x+y)
, dp[i] = max(dp[x], x) * max(dp[y], y);
代码
class Solution {
public:int integerBreak(int n) {vector<int> dp(n+1, INT_MIN);dp[0] = 0;dp[1] = 0;dp[2] = 1;if(n<=2)return dp[n];for(int i=3; i<=n; ++i){for(int x=1; x<=i/2; ++x){int y = i-x;dp[i] = max(dp[i], max(dp[x], x) * max(dp[y], y));}}return dp[n];}
};
进一步优化
可以将递推构建dp数组的过程进一步简化为以下形式
效率会更高, 但是理解起来困难一些, 也不容易想到
for (int i = 3; i <= n ; i++) {for (int j = 1; j <= i / 2; j++) {dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));}
}
96.不同的二叉搜索树
题目描述
LeetCode链接:https://leetcode.cn/problems/unique-binary-search-trees/description/
解题思路
动态规划
dp
数组中dp[i]
表示有i
个节点的时候有dp[i]
种搜素树
dp[0]=0
, dp[1]=1
, dp[2]=2
求dp[i]
的时候, 用j遍历1到i
, dp[i] += dp[j-1] * dp[i-j];
代码
class Solution {
public:int numTrees(int n) {vector<int> dp(max(n+1,5),0);dp[0] =1;dp[1] = 1;dp[2] = 2;if(n<=2)return dp[n];for(int i=3; i<=n; ++i){for(int j=1; j<=i; ++j){dp[i] += dp[j-1] * dp[i-j];}}return dp[n];}
};
优化改进
不用初始化到2, 到1就行了
class Solution {
public:int numTrees(int n) {vector<int> dp(n+1,0);dp[0] =1;dp[1] = 1;for(int i=2; i<=n; ++i){for(int j=1; j<=i; ++j){dp[i] += dp[j-1] * dp[i-j];}}return dp[n];}
};
总结
很多动态规划题目, 因为涉及到递推, 前后数值的查询, 所以直接脑中空想比较困难;
想不清楚的时候最好动笔写写画画, 思路会清晰很多.
本文参考:
整数拆分
不同的二叉搜索树