- 第一种方法,暴力法递归。
class Solution {
public:
int DFS(vector<vector<int>>& triangle, int i, int j) {
if (i == triangle.size()-1)
return triangle[i][j];//一开始写成了triangle[0][0]
//画递归树调试递归
int left = DFS(triangle, i + 1, j);
int right = DFS(triangle, i + 1, j + 1);
return triangle[i][j] + min(left,right);//加断点进行调试
}
int minimumTotal(vector<vector<int>>& triangle) {
int level = 0, i = 0, j = 0;
return DFS(triangle, i, j);
}
};
写一下需要注意的调试过程
上面画的这张图显示了递归过程调用某子过程的先后顺序。 参照代码中加的断点可以逐渐分析出代码的bug。另外从上图可以看出某些子过程被调用了多次,所以想到从下而上每次记录下来每个子过程的结果,也就引出了动态规划。
2.第二种方法,动态规划
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int size = triangle.size();
//一开始想找到最长的那一行的大小,然后复制这一行给memo,其实不用,
//题目给的形式最后一行是最长的。
//int maxsize = triangle[0].size();
//for (int i = 0; i < triangle.size(); i++) {
//if (maxsize < triangle[i].size())
//maxsize = triangle[i].size();
//}
//直接用这样的方式把triangle的最后一行给复制过来了,很简便,省了不少事。
vector<int>memo(triangle.back());
//memo[0] = 4;
//memo[1] = 1;
//memo[2] = 8;
//memo[3] = 3;
//for (int i = 0; i < triangle[size - 1].size(); i++) {
//memo[i] = triangle[size - 1][i];
//}
for (int i = triangle.size() - 2; i >= 0; i--) {
for (int j = 0; j < triangle[i].size(); j++) {
memo[j] = triangle[i][j]+ min(memo[j], memo[j + 1]);
}
}
return memo[0];
}
};