LeetCode120: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
这里写图片描述
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)的空间复杂度内求解问题,前面矩阵中的最短路径中的解法二就是在O(n)空间复杂度内求解的,这里可以借鉴一下。
分析:
设A[i][j]表示到triangle[i][j]的最短路径,那么

  1. if j==0 : A[i][j]=A[i-1][j]+triangle[i][j]
  2. else if j==width-1 : A[i][j]=A[i-1][j-1]+triangle[i][j]
  3. else A[i][j]=min{A[i-1][j-1],A[i-1][j]}+triangle[i][j]

由于A[i][j]只与A[i-1][j-1]和A[i-1][j]有关,那么可以只保留这两行的数据,解法一就是使用preRow保留i-1行的数据,curRow保留当前行的数据。
时间复杂度O(N^2),空间复杂度O(N)。
runtime:8ms


解法一:

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int height=triangle.size();
        vector<int> curRow(height,0);
        vector<int> preRow(height,0);
        for(int i=0;i<height;i++)
        {
            int width=triangle[i].size();
            for(int j=0;j<width;j++)
            {
                if(j==0)
                    curRow[0]=preRow[0]+triangle[i][j];
                else if(j==width-1)
                    curRow[j]=preRow[j-1]+triangle[i][j];
                else
                    curRow[j]=min(preRow[j-1],preRow[j])+triangle[i][j];
            }
            preRow=curRow;
        }

        int ans=INT_MAX;
        for(int i=0;i<height;i++)
        {
            ans=min(ans,curRow[i]);
        }

        return ans;
    }
};

解法二:

注意到preRow的使用方式,可以进一步优化,如果对j进行从右到左遍历,那么可以只用一个数组来保存数据。

class Solution {
public:  
    int minimumTotal(vector<vector<int>>& triangle) {
         int height=triangle.size();
        vector<int> curRow(height,0);
        for(int i=0;i<height;i++)
        {
            int width=triangle[i].size();
            for(int j=width-1;j>=0;j--)
            {
                if(j==0)
                    curRow[0]+=triangle[i][j];
                else if(j==width-1)
                    curRow[j]=curRow[j-1]+triangle[i][j];
                else
                    curRow[j]=min(curRow[j-1],curRow[j])+triangle[i][j];
            }
        }

        int ans=INT_MAX;
        for(int i=0;i<height;i++)
        {
            ans=min(ans,curRow[i]);
        }

        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值