算法训练营day34(12.2)
2024-12-01 本文已影响0人
无心浪子
题目1: 62. 不同路径
算法思路:
只能向下或者向右移动,因此第一行和第一列的结果都为1.
然后根据dp[i][j] = dp[i - 1][j] + dp[i][j - 1]计算其他所有的值并返回需要的结果。
代码:
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m, vector<int>(n));
for(int j = 0; j < n; j++) dp[0][j] = 1;
for(int i = 1; i < m; i++) dp[i][0] = 1;
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
}
};
题目 2: 63. 不同路径 II
算法思路:
递推公式和上一道题目一样,只是需要考虑所在位置有障碍物的情况下其值为0即可。
代码如下:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector<vector<int>> dp(m, vector<int>(n));
for(int i = 0; i < m &&!obstacleGrid[i][0]; i++) dp[i][0] = 1;
for(int j = 0; j < n &&!obstacleGrid[0][j]; j++) dp[0][j] = 1;
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
if(!obstacleGrid[i][j]) {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
}
}
}
return dp[m - 1][n - 1];
}
};
题目3: 343. 整数拆分
算法思路:
对于每个整数,遍历所有情况下拆分后某数和某个序列拆分数相乘的最大值即可。
代码:
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n+1);
dp[2] = 1;
for(int i = 3; i <= n; i++) {
for(int j = 1; j <= i / 2; j++) {
dp[i] = max(dp[i], max((i -j) * j, j * dp[i - j]));
}
}
return dp[n];
}
};
题目4: 96. 不同的二叉搜索树
算法思路:
所求结果即以每个可能的根结点值对应左右子树的情况相乘和。
代码如下:
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1);
dp[0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
};