【leetcode】120. Triangle

来源:互联网 发布:堆量选股公式 源码 编辑:程序博客网 时间:2024/06/05 14:27

Difficulty:medium

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.

解题思路一(递归时间复杂度为2^n):

首先考虑使用递归的方法,如果从上至下采用递归的动态规划,那么可以将每一个数字的结果分为两部分:triangle[i][j]+min(triangle[i+1][j],triangle[i+1][j+1].这样就需要求解triangle[i+1][j],和triangle[i+1][j+1]的值,依次类推,当计算到向量的底部时,向上回硕得到了最终的结果。

但是这样的时间复杂度相对来说较高,因为在自上向下的递归过程中,对于某一个triangle[i][j],都需要进行两次的计算,因为在他的上次层有triangle[i-1][j],和triangle[i-1][j+1]用到这个数字,所以在递归的过程中难免会将同一个数值计算两次,这样导致最终的计算量大幅度上升,时间复杂度达到了O(2^n)。采用递归的方法所需要的额外空间只有n;

解题思路二(动态规划时间复杂度n*n):

再考虑使用动态规划自底向上的递推过程,考虑到如果重复计算同一个值会使程序的计算量大幅度上升,所以从下向上,如果需要计算出triangle[i][j],那么下层的triangle[i+1][j]和triangle[i+1][j+1]都已经是已知的了,并且同样的计算triangle[i][j+1]的时候,需要用到triangle[i+1][j+1]和triangle[i+1][j+2],但是计算triangle[i+1][j]时用到的triangle[i+1][j+1]已经在下层计算过不需要重复的计算量,与triangle[i][j]计算过程中用到的triangle[i+1][j+1]的值相同。所以避免了上层用到同一个值时所进行的无谓的计算量。

因为题目中要求了要最多使用n的额外空间,所以开出一个能容纳每一个位置到底部的最短距离的向量arr[n*(n-1)/2+1],对于每一个位置,通过i,j来计算在arr中的位置,在triangle中triangle[i][j]到底部的最短距离就是arr[(i)*(i-1)/2+j]的值,所以最后需要求的就是arr[0]。

接下来就是要控制好进行两层循环的界限,以及在动态规划过程中的状态传递方程

从下到上 for(int i=n-1;i>=0;i--)控制每一层的层数,for(int j=0;j<=i;j++)用来控制在当前层每一个位置的arr[(i)*(i-1)/2+j]的值。

状态传递方程为arr[(i)*(i-1)/2+j] = triangle[i][j]+min(arr[(i+1)*(i)/2+j],arr[(i+1)*(i)/2+j+1]);

最终返回arr[0]的值即可。最终的时间复杂度为O(n*n)相对于递归过程如果数据量很大的时候将会有明显的对比。并且额外空间同样为n

代码如下:

int min(int a,int b){if(a<b) return a;else return b;}class Solution {public:    int minimumTotal(vector<vector<int>>& triangle) {        int n=triangle.size();int *arr=new int[n*(n-1)/2+1];for(int i=n-1;i>=0;i--){for(int j=0;j<=i;j++){if(i==n-1) arr[(i)*(i-1)/2+j] = triangle[i][j];else if(i!=n-1) arr[(i)*(i-1)/2+j] = triangle[i][j]+min(arr[(i+1)*(i)/2+j],arr[(i+1)*(i)/2+j+1]);}}int ans=arr[0];return ans;    }};



0 0
原创粉丝点击