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.
显然,本题是一道动态规划问题,最直接的做法就是用二维数组存放当前位置的最小值
public int MinimumTotal(IList<IList<int>> triangle)
{
int n = triangle.Count;
if (n == 1)
return triangle[0][0];
int[,] sum = new int[n,n];
sum[0, 0] = triangle[0][0];
for (int i = 1; i < n; i++)
{
sum[i,0]= triangle[i][0]+sum[i-1,0];
for (int j = 1; j < i; j++)
sum[i, j]= triangle[i][j]+Math.Min(sum[i - 1,j-1], sum[i - 1,j]);
sum[i, i] = triangle[i][i] + sum[i - 1,i - 1];
}
int min = sum[n - 1, 0];
for (int i = 1; i < n; i++)
{
if (sum[n - 1, i] < min)
min = sum[n - 1, i];
}
return min;
}
优化:
把二维数组用一维数组替换,但是要注意赋值的顺序要倒着来,否则会覆盖掉有用的值
public int MinimumTotal(IList<IList<int>> triangle)
{
int n = triangle.Count;
if (n == 1)
return triangle[0][0];
int[] sum = new int[n];
sum[0] = triangle[0][0];
for (int i = 1; i < n; i++)
{
sum[i] = triangle[i][i] + sum[i - 1];
for (int j = i-1; j >=1; j--)
sum[j]= triangle[i][j]+Math.Min(sum[j-1], sum[j]);
sum[0] += triangle[i][0];
}
int min = sum[0];
for (int i = 1; i < n; i++)
{
if (sum[i] < min)
min = sum[i];
}
return min;
}
再优化:
倒序!
public int MinimumTotal(IList<IList<int>> triangle)
{
int n = triangle.Count;
if (n == 1)
return triangle[0][0];
int[] sum = new int[n];
for (int i = 0; i < n; i++)
sum[i] = triangle[n - 1][i];//拷贝最后一行
for (int i = n-2; i >=0; i--)
{
for (int j = 0; j <=i; j++)
sum[j] = triangle[i][j] + Math.Min(sum[j+1], sum[j]);
}
return sum[0];
}