Triangle Path 寻找最小和路径

142 篇文章 20 订阅
21 篇文章 0 订阅

问题: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).

思路:有点最短路径的意味。不能用贪心法。 比如说下面这个例子,用贪心就错了。

[
     [2],
    [3,4],
   [6,5,7],
  [9,9,8,1]
]
必须动态规划的逐层算出到达每个位置的最小路径和,直到底层。

方法一:用原输入数据中做修改,记录最小路径和。时间复杂度O(N^2),空间复杂度O(1)。好处是不用再申请空间。坏处是破坏了原数据。

class Solution {
public:
    int min(int a, int b)
    {
        return a>b?b:a;
    }
    int minimumTotal(vector<vector<int> > &triangle) {
        int row = triangle.size();
        if(row == 0)
            return 0;
        if(row == 1)
            return triangle[0][0];
        int i,j;
        for(i=1;i<row;i++)
        {
            triangle[i][0] += triangle[i-1][0];
            for(j=1;j<i;j++)
            {
                triangle[i][j] += min(triangle[i-1][j-1], triangle[i-1][j]);
            }
            triangle[i][j] += triangle[i-1][j-1];
        }
        
        int minsum = triangle[row-1][0];
        for(i=1;i<row;i++)
            if(triangle[row-1][i] < minsum)
                minsum = triangle[row-1][i];
        return minsum;
    }
};

方法二:如果要求不可以破坏原数据。申请一个临时一维数组(长度为最低层的长度),每次都用它维护每层的最小路径和。

注意:在更新每层最小路径和的时候,会发现由于每个数都需要用两次,是第一次更新后就被刷掉了,第二次没办法更新。

换一个方向,海阔天空。从下向上来,由于这个方向是先比较大小后选较小的来更新数据,数越来越少,不存在数据丢失的问题。并且,上升到最顶端只剩下一个数,直接得到结果。时间复杂度O(N^2),空间复杂度O(N)。

class Solution {
public:
    int min(int &a, int &b)
    {
        return a>b?b:a;
    }
    int minimumTotal(vector<vector<int> > &triangle) {
        int row = triangle.size();
        if(row == 0)
            return 0;
        if(row == 1)
            return triangle[0][0];
        
        int *T = new int[row];
        int i,j;
        for(i=0;i<row;i++)
            T[i] = triangle[row-1][i];
        
        for(i=row-2;i>=0;i--)
        {
            for(j=0;j<=i;j++)
            {
                T[j] =  triangle[i][j] + min(T[j], T[j+1]);
            }
        }
        int minsum = T[0];
        delete[] T;
        return minsum;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值