室内设计毕业设计代做网站,建站平台免代码,房地产开发公司名字,惠州百度网络推广题目与题解
343. 整数拆分 题目链接#xff1a;343. 整数拆分 代码随想录题解#xff1a;343. 整数拆分 视频讲解#xff1a;动态规划#xff0c;本题关键在于理解递推公式#xff01;| LeetCode#xff1a;343. 整数拆分_哔哩哔哩_bilibili 解题思路#xff1a; 一眼懵…题目与题解
343. 整数拆分 题目链接343. 整数拆分 代码随想录题解343. 整数拆分 视频讲解动态规划本题关键在于理解递推公式| LeetCode343. 整数拆分_哔哩哔哩_bilibili 解题思路 一眼懵直接看答案了
看完代码随想录之后的想法 前一天的题是由dp[i-2]和dp[i-1]递推出当前结果dp[i]。这题更复杂一些是要根据dp[0]到dp[i-1]推算dp[i]的结果。 对于数字i可以分解为两个数字的和j和i-j因此求分解i的乘积就是求j和分解i-j之后二者的乘积。那么如果dp[i]定义为数字i的最大乘积和那么对于dp[i]遍历j from 1 to i - 1, 递推公式为求dp[i-j]*j和j * (i - j) 中的最大值。 为避免重复计算j最多取到i的一半。
class Solution {public int integerBreak(int n) {int[] dp new int[n1];if (n 2) 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(j*(i-j), dp[i-j]*j));}}return dp[n];}
}
j怎么就不拆分呢
j是从1开始遍历拆分j的情况在遍历j的过程中其实都计算过了。那么从1遍历j比较(i - j) * j和dp[i - j] * j 取最大的。递推公式dp[i] max(dp[i], max((i - j) * j, dp[i - j] * j));
也可以这么理解j * (i - j) 是单纯的把整数拆分为两个数相乘而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。
如果定义dp[i - j] * dp[j] 也是默认将一个数强制拆成4份以及4份以上了。
所以递推公式dp[i] max({dp[i], (i - j) * j, dp[i - j] * j}); 还需要注意初始化的方式是跟着定义走的如果求的是maxdp[i - j] * dp[j]为了计算正确初始化的结果会跟dp[i]定义不符容易出错。
遇到的困难 第一次碰到这种题想不到
96.不同的二叉搜索树 题目链接96.不同的二叉搜索树 代码随想录题解96.不同的二叉搜索树 视频讲解动态规划找到子状态之间的关系很重要| LeetCode96.不同的二叉搜索树_哔哩哔哩_bilibili 解题思路 这题跟上面一题有一点类似同样是要用多个dp[i-j]的值推出dp[i]。 题目要求用1-n的数字构成不同的二叉搜索树其实可以分解为0-j-1的数字构成左子树j为根节点j到i构成右子树那么 初始化dp[0]dp[1]0即可。
class Solution {public int numTrees(int n) {int[] dp new int[n1];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];}
}
看完代码随想录之后的想法 以dp[3]为例
dp[3]就是 元素1为头结点搜索树的数量 元素2为头结点搜索树的数量 元素3为头结点搜索树的数量
元素1为头结点搜索树的数量 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量
元素2为头结点搜索树的数量 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量
元素3为头结点搜索树的数量 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量
关键是看如何去分解分解后如何正确确定遍历的上下限。
遇到的困难 一开始写的时候没有想清楚遍历的边界初始化的时候也有点糊涂所以错了好几处。要记住按定义初始化dp然后确定遍历上下界后最好通过几个举例得到结果保证边界正确。
今日收获 学会了如何用分解的方法使用dp难度提升了很多。