题目链接:https://leetcode.com/problems/triangle/
一看题目,感觉是暴力搜索能解,但看到问题下面有个Notes: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.看到这里就开始直接思考O(n)空间复杂度的解法,突然有了想法,如果能够直接修改List里的值的话这个空间复杂度岂不是到了O(1),这里不行。就用长度为n的数组来存遍历到当前第i排的每个位置上到达前i个位置(当前的数组实际占用大小为i,随着排数增加而增加1)的最小路径和,代码如下:
class Solution {
public int minimumTotal(List<List<Integer>> triangle)
{
int[] ans=new int[triangle.size()];
ans[0]=triangle.get(0).get(0);
int me=0,mo=0;
for(int i=1;i<triangle.size();i++)
{
List<Integer> row=triangle.get(i);
me=ans[0];
ans[0]=row.get(0)+me;
for(int j=1;j<row.size()-1;j++)
{
mo=ans[j];
ans[j]=row.get(j)+Math.min(me,mo);
me=mo;
}
ans[row.size()-1]=row.get(row.size()-1)+me;
}
int ret=Integer.MAX_VALUE;
for(int i=0;i<triangle.size();i++)
ret=Math.min(ret,ans[i]);
return ret;
}
}
空间复杂度为O(n)。一遍AC,爽歪歪,效率还行,Beat 50%!!!
还有一种思路类似的动态规划来解的,空间复杂度O(n),代码如下:
public int minimumTotal(List<List<Integer>> triangle)
{
if (triangle.size() == 0) {
return 0;
}
int n = triangle.size();
int[] dp = new int[n];
for (int i = 0; i < n; i++) {
dp[i] = triangle.get(n - 1).get(i);
}
for (int i = n - 2; i >= 0; i--)
{
for (int j = 0; j <= i; j++)
{
int val = triangle.get(i).get(j);
dp[j] = val + Math.min(dp[j], dp[j + 1]);
}
}
return dp[0];
}
还有一种空间复杂度为O(n^2)的解法,说白了跟上面思路是一致的,只不过是在答案覆盖改写前是否缓存上一个最佳答案,这里不再赘述,代码如下:
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle.size() == 0) {
return 0;
}
int n = triangle.size();
int[][] dp = new int[triangle.size()][];
for (int i = 0; i < n; i++) {
dp[i] = new int[i + 1];
if (i == n - 1) {
for (int j = 0; j < n; j++) {
dp[i][j] = triangle.get(i).get(j);
}
}
}
for (int i = n - 2; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
int val = triangle.get(i).get(j);
dp[i][j] = val + Math.min(dp[i + 1][j], dp[i + 1][j + 1]);
}
}
return dp[0][0];
}