算法设计与应用基础:第十二周(1)

关于由下到上和由上到下以及空间复杂度的改进

120. Triangle

  • Total Accepted: 100621
  • Total Submissions: 303569
  • Difficulty: Medium
  • Contributor: LeetCode

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.

Subscribe to see which companies asked this question.

解题报告:拿到这道题的第一思路是用贪心,但是敲了代码发现贪心由上到下的最优子结构无法保证总的最优结构,所以这道题不能用贪心算法。寻找其他的子结构,发现由下到上的动态规划是可行的,对于从倒数第二行开始,满足triangle[i][j] +=min(triangle[i+1][j+1],triangle[i+1][j]); 所以想到用递归来写,但是敲完submit发现超时,leetcode好多题不能用递归,应嘎是栈模拟时耗时太多。然后就卡在如何把这个递归写成递推的for循环,可能是暂时的思维定式想了半天也没想出来,最后查看discuss发现了原来是如此的简单,同样遵循由下到上,从倒数第二行开始用递推式回推最后得到答案在top点。但是注意到题中要求空间复杂度为O(n),再次陷入沉思(对于空间复杂度的改进一直是弱项),再次百度之明白了道理,递推的任意时刻只需要当前所在行的下一行的信息,于是只需要一直保存上次更新完的vector信息就可以了,成功将extra space 缩小到n。代码如下

int minimumTotal(vector<vector<int> > &triangle) {  
      vector<int> ans(triangle.back());
      for(int i=triangle.size()-2;i>=0;i--)
      {
          for(int p=0;p<triangle[i].size();p++)
          {
              ans[p]=min(ans[p],ans[p+1])+triangle[i][p];
          }
      }
      return ans[0];
    /*for (int i = triangle.size() - 2; i >= 0; --i)  
      for (int j = 0; j <= i; ++j){  
          
        triangle[i][j] +=min(triangle[i+1][j+1],triangle[i+1][j]);  
      }  
      
    return triangle[0][0];  */
  }  
总结:学到了两个方法,自下向上的回推(包含在其中的递归转换为递推),空间复杂度的减小(高阶方法)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值