LeetCode 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 is 11
(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.
很明显、经典的DP问题。题目要求最好使用O(n)的空间来完成。
方法一:自顶向下,但是貌似空间利用率超过了O(n)
关键思想是逐层累计,用一个数组来保存累计的值。累计式:
arr[i] = min(arr[i-1] + triangle[i][j], arr[i] + triangle[i][j])//j表示第i行的下标
最后arr中最小值就是所要的结果。
int minimumTotal(vector<vector<int> > &triangle)
{
int m = triangle.size();
if (m == 0)
return 0;
int n = triangle[m - 1].size();
int *arr = new int[n];
arr[0] = triangle[0][0];
//从第二行开始
for (int i = 1; i < m; i++)
{
int col = triangle[i].size();
//零时存储的数组,以免改变了原来保存在arr中的数据
int * tmpArr = new int[col];
for (int j = 1; j < col - 1; j++)
tmpArr[j] = (arr[j - 1] + triangle[i][j] <= arr[j] + triangle[i][j]) ? (arr[j - 1] + triangle[i][j]) : (arr[j] + triangle[i][j]);
//把arr的最左边和最右边计算出来,以及把tmpArr的数据放到arr中
arr[col - 1] = arr[col - 2] + triangle[i][col - 1];
arr[0] += triangle[i][0];
for (int j = 1; j < col - 1; j++)
arr[j] = tmpArr[j];
delete tmpArr;
}
//排个序,第一个就是最小的
sort(arr, arr + n);
int res = arr[0];
delete arr;
return res;
}
中间申请了tmpArr来保存零时的数据,以免叠加的时候arr数组部分数据被覆盖。
方法二:自底向上
int minimumTotal(vector<vector<int> > &triangle) {
if (triangle.size() == 0)
return 0;
int m = triangle.size();
int n = triangle[m - 1].size();
int *arr = new int[n];
//将三角形最底层一行的数据给arr初始化
for (int i = 0; i < n; i++)
arr[i] = triangle[m - 1][i];
for (int i = n - 2; i >= 0; i--)
{
for (int j = 0; j <= i; j++)
{
arr[j] = min(arr[j] + triangle[i][j], arr[j + 1] + triangle[i][j]);
}
}
int res = arr[0];
delete arr;
return res;
}
};
方法三:自底向上,不用空间。(参看人家的)
int minimumTotal(vector<vector<int> > &triangle) {
for (int i = triangle.size() - 2; i >= 0; --i)
{
for (int j = 0; j < triangle[i].size(); ++j)
{
triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1]);
}
}
return triangle[0][0];
}