每日leetcode
整数拆分
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。
这道题的话,也是五部曲
1、dp[i]代表i拆分的最大乘积
2、dp[i] = max(dp[i], max((i-j)*j, dp[i-j]*j)); 而且不需要遍历所有的j,只需要遍历一半就可以了,因为显然,如果将给定的正整数拆分成尽可能多的某个特定的正整数,则这些正整数的乘积最大。所以如果对于dp[n] n >=2 ,至少要分成两份,所以只要遍历一半就可以了。
3、初始值的话,dp[0]和dp[1]是没有意义的,因为拆成两个数,乘积一定会变小,所以从2开始,dp[2] = 1;
4、前向
5、模拟:
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n+1, 0);
// dp1和dp0没有意义,因为拆出来也会减少乘积,一定不是最大乘积
dp[2] = 1;
for(int i = 3; i <= n; i++)
for(int j = 1; j <= i/2; j++)
dp[i] = max(dp[i], max(j *(i - j), j * dp[i-j]));
return dp[n];
}
};
不同的二叉搜索树
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
这道题的话要找规律,规律就是二叉搜索树,是从左滚到右,对称的。而且随着n的增加,二叉搜索树会不断的继承之前搜索树的特点。也就是:
链接:
https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0096.%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.md
所以,五部曲:
1、dp[i],i个结点的二叉搜索树的个数
2、dp[i] += dp[j]*dp[i-j];
3、dp[0] = 1;(就代表节点某个子树为空的情况)
4、前向
5、模拟:
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 = 0; j < i; j++){
dp[i] += dp[j] * dp[i-1-j];
}
}
return dp[n];
}
};
这道题还是蛮难想的。
effective c++
条款19 设计class犹如设计type
就是自己设计class要转专业,要考虑其可用性,合理性,安全性等等。