LeetCode 120 Triangle

来源:互联网 发布:win 7设置家庭网络 编辑:程序博客网 时间:2024/05/16 13:55

120. 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.


题意:通过二维数组给定一个三角形,要求找出从顶端到底部最小路径之和,并且每次移动只能在相邻元素之间移动,此外,特别要求,本题解法的空间复杂度最好能够为O(n)。


分析:简单的动态规划,每次选择下一行的数字都只能选择相邻元素,对题给例子来说,2的相邻元素就是3和4,3的相邻元素就是6和5,而5的相邻元素即为1和8,根据这些元素的下标,易知,对于元素triangle[i][j]来说,其相邻元素就是triangle[i][j+1]triangle[i+1][j+1],从triangle[i][j]到下一行的最小路径之和即为:triangle[i][j]+min(triangle[i][j+1],triangle[i+1][j+1])

假设用dist[i][j]表示从原点到第i行第j列元素的最小路径之后,那么有:

dist[i][j]=triangle[i][j]+min(dist[i][j+1],dist[i+1][j+1])

遍历完整个数组就可得到从原点到底部的最小路径之和,时间复杂度为O(n)。


回到题目的另一个要求:空间复杂度O(n)

上述的假设显然是需要一个O(n^2)的额外空间,通过动态规划解决问题,用dist[i][j]作为子问题,每次更新dist[i][j]时就会用到dist[i][j+1]和dist[i+1][j+1],而且每步只用到了前一步的dist,用过了就不再需要了,那么我们就可以用同一个空间来存储dist[i],每步更新dist[i],由于路径中的最后一步需要n个空间来存储,而倒数第二步需要前面的n-1个空间,以此递推可知第一步只需要一个空间空间复杂度为O(n)。

以题目所给为例,从路径的最后一步开始,以最后一个数组的元素作为dist[i]的初始值,dist[i]保存的是到达第i个点的最小路径之和:

dist[i]=triangle[n-1]=[4,1,8,3]
更新一次,向上遍历数组,用min(dist[i],dist[i+1])与triangle[n-2][i]之和更新dist数组:

dist[i]=[min(4,1)+6,min(1,8)+5,min(8,3)+7,3]=[7,6,10,3]
继续往上遍历:

dist[i]=[min(7,6)+3,min(6,10)+4,10,3]=[9,10,10,3]
dist[i]=[min(9,10)+2,13,10,3]=[11,13,10,3]
最终可得:dist[0]=1+5+3+2=11,即为所求的最先路径之和。


代码实现如下:

class Solution {public:int minimumTotal(vector<vector<int>>& triangle) {vector<int> dist = triangle[triangle.size() - 1];for (int i = triangle.size() - 2; i >= 0; i--) {for (int j = 0; j < triangle[i].size(); j++) {dist[j] = triangle[i][j] + (dist[j] > dist[j+1] ? dist[j+1] : dist[j]);}}return dist[0];}};





原创粉丝点击