120. Triangle
题目
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to bottom is11
(i.e., 2 + 3 + 5 + 1 = 11).Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
分析
- 这一道题其实比起之前的寻路的个数难度降低了,只不过形态比较奇怪,所以刚开始看起来可能会感到困惑
- 也就是杨辉三角形的变形,只不过每一个三角形底边的新生成采用局部贪心算法的模式,也就是一直去最小值就可以了。
- 步骤可以简化为如下:(i表示行, j表示列, 存储的数组为M)
- 当j为0的时候,则M[i][j] = M[i - 1][j] + a[i][j]
- 当j等于i的时候,则M[i][j] = M[i - 1][j] + a[i][j]
- 其余的情况,M[i][j] = min(M[i - 1][j - 1], M[i - 1][j]) + a[i][j]
题解
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int l = triangle.size();
int a1[l][l];
a1[0][0] = triangle[0][0];
for(int i = 1; i < l; i++){
for(int j = 0; j <= i; j++){
if(j == 0) a1[i][j] = a1[i - 1][0] + triangle[i][j];
else if(j == i) a1[i][j] = a1[i - 1][j - 1] + triangle[i][j];
else {
a1[i][j] = min(a1[i - 1][j - 1], a1[i - 1][j]) + triangle[i][j];
}
}
}
int minnum = a1[l - 1][0];
for(int i = 0; i < l; i++){
if (a1[l - 1][i] < minnum){
minnum = a1[l - 1][i];
}
}
return minnum;
}
};
97. Interleaving String
题目
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
Example 1:
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true
分析
- 一开始看这一道题的思路与之前做过的正则表达式匹配的思路是一样的,因为自己理解成了只要存在一个两者合并的方式就可以了,因此采用的是递归的方式,但是当字符串的长度较长的时候算法的复杂度已经很高了,也就是会造成超时,所以就应该另寻方法
- 采用二维数组的动态规划算法
- 开一个大小为M[s1.length() + 1][s2.length() + 1]的数组
- M[i][j]表示的是在s1中取前i个字符以及s2中取前j个字符是否能够构成s3中的i+j个字符串,依赖于前面的值
- 一开始的初始化:
- M[0][0] = true
- 分别对s1与s2进行M[i][0] M[0][j]的赋值操作:M[i][0] = M[i - 1][0] && s1[i - 1] == s3[i - 1];
- 在进行遍历填表
- M[i][j] = (M[i][j - 1] && s2[j - 1] == s3[i + j - 1]) || (M[i - 1][j] && s1[i - 1] == s3[i + j - 1]);
题解
错解(复杂度较高)
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
if(s3 == "") return s1.empty() && s2.empty();
if(s1 == "") return (s2 == s3);
if(s2 == "") return (s1 == s3);
if(s3[0] == s1[0] && s3[0] == s2[0]){
return isInterleave(s1.substr(1, s1.length() - 1), s2, s3.substr(1, s3.length() - 1)) || isInterleave(s1, s2.substr(1, s2.length() - 1), s3.substr(1, s3.length() - 1));
}
else if(s3[0] == s1[0]) return isInterleave(s1.substr(1, s1.length() - 1), s2, s3.substr(1, s3.length() - 1));
else if(s3[0] == s2[0]) return isInterleave(s1, s2.substr(1, s2.length() - 1), s3.substr(1, s3.length() - 1));
else return false;
}
};
正解
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int l1 = s1.length();
int l2 = s2.length();
int l3 = s3.length();
if((l1 + l2) != l3) return false;
bool M[l1+1][l2+1];
M[0][0] = true;
for(int i = 1; i <= l1; i++){
M[i][0] = M[i - 1][0] && s1[i - 1] == s3[i - 1];
}
for(int j = 1; j <= l2; j++){
M[0][j] = M[0][j - 1] && s2[j - 1] == s3[j - 1];
}
for(int i = 1; i <=l1; i++){
for(int j = 1; j <= l2; j++){
M[i][j] = (M[i][j - 1] && s2[j - 1] == s3[i + j - 1]) || (M[i - 1][j] && s1[i - 1] == s3[i + j - 1]);
}
}
return M[l1][l2];
}
};