题目为 给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。
开始的思路为递归,按照类似深度遍历的方式去遍历整个列表。复杂度较高,代码执行至倒数第二个案例超时,代码如下
/*给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。*/
public int MinimumTotal(IList<IList<int>> triangle)
{
int lastRow = triangle.Count();
GetNum(triangle, 0, 0, 0);
return resMin;
}
int resMin = int.MaxValue;
public void GetNum(IList<IList<int>> li,int Rows, int Columns,int begin)
{
//最底层行添加至结果集合
if (Rows==li.Count()-1)
{
int minLeft = li[Rows][Columns] + begin;
if (resMin>minLeft)
{
resMin = minLeft;
}
if (li[Rows].Count() - 1 >= Columns + 1)
{
int resRight = li[Rows][Columns + 1] + begin;
if (resRight<resMin)
{
resMin = resRight;
}
}
return;
}
if (Rows==0)
{
int now = li[Rows][Columns] + begin;
GetNum(li, Rows + 1, Columns, now);
GetNum(li, Rows + 1, Columns + 1, now);
}
else
{
int now = li[Rows][Columns] + begin;
GetNum(li, Rows + 1, Columns, now);
if (li[Rows].Count() - 1 >= Columns + 1)
{
int nowRight = li[Rows][Columns + 1] + begin;
GetNum(li, Rows + 1, Columns + 1, nowRight);
}
}
return;
}
看了题解,题解的思路是对于以下数组
[1]
[2,3]
[4,5,6]
到达5元素只能从5的上方和左上元素到达。那么我们可以找最小的元素当作到该点前的最小值。代码如下
public int MinimumTotal(IList<IList<int>> triangle)
{
//从上到下进行遍历
int countAll = triangle.Count();
int[] liRes = new int[countAll];
//第一行遍历的值肯定为第一行第一个元素值
liRes[0] = triangle[0][0];
//行
for (int i = 1; i < countAll; i++)
{
//最右侧值 为左上角元素加最右侧元素
liRes[i] = liRes[i - 1] + triangle[i][i];
//列 从右侧向左赋值 因为如果从左向右会影响右侧的值(右侧是从左侧的值来的)
for (int j = triangle[i].Count() - 2; j >= 1; j--)
{
if (liRes[j] > liRes[j - 1])
{
liRes[j] = liRes[j - 1]+ triangle[i][j];
}
else
{
liRes[j] = liRes[j] + triangle[i][j];
}
}
//最左侧值只能从上方元素来
liRes[0] = liRes[0] + triangle[i][0];
}
return liRes.Min();
}