lintcode triangle 数字三角形

问题描述

lintcode

笔记

代码1

设置buff[i][j]为:以元素(i,j)结尾的最小路径和。
buff[i][j]应该是buff[i-1][j-1]buff[i-1][j]中的较小值再加上当前的triangle[i][j]
则状态转移方程为:
buff[i][j] = min(buff[i-1][j-1], buff[i-1][j] + triangle[i][j]
初始条件为:
buff[0][0] = triangle[0][0]

注意

判断越界问题也用到了一个小技巧,忘了从哪学来的了。

//要取buff[i-1][j-1],和buff[i-1][j],但是要保证不越界。
//第i-1行的j的取值范围为[0, i-1]
int lo = max(0, j-1);//当j-1小于0的时候只取0,大于等于0的时候取自身。
int hi = min(j, i-1);//当j大于i-1的时候只取i-1,小于等于i-1的时候取自身。

代码2

题目要求优化空间复杂度。其实不需要用二维数组,因为每一行的值只与上一行的值相关,因此可以只用一行做缓存即可。(代码2)
在这里用到了背包问题中的小技巧,每一行从后往前更新,以防覆盖前面要使用的值。

注意

看来,要将二维空间节省成一维空间的时候,都要考虑一下从后往前向前更新这一小技巧。

代码1

class Solution {
public:
    /**
     * @param triangle: a list of lists of integers.
     * @return: An integer, minimum path sum.
     */
    int minimumTotal(vector<vector<int> > &triangle) {
        // write your code here
        const int len = triangle.size();
        vector<vector<int>> buff(len, vector<int>(len));
        buff[0][0] = triangle[0][0];
        for (int i = 1; i < len; i++)
        {
            for (int j = 0; j <= i; j++)
            {
                // 要取buff[i-1][j-1],和buff[i-1][j],但是要保证不越界。
                // 第i-1行的j的取值范围为[0, i-1]
                int lo = max(0, j-1);
                int hi = min(j, i-1);
                buff[i][j] = min(buff[i-1][lo], buff[i-1][hi]) + triangle[i][j];
            }
        }
        int res = buff[len-1][0];
        for (int i = 1; i < len; i++)
            res = min(res, buff[len-1][i]);
        return res;
    }
};

代码2

class Solution {
public:
    /**
     * @param triangle: a list of lists of integers.
     * @return: An integer, minimum path sum.
     */
    int minimumTotal(vector<vector<int> > &triangle) {
        // write your code here
        const int len = triangle.size();
        vector<int> buff(len);
        buff[0] = triangle[0][0];
        for (int i = 1; i < len; i++)
        {
            for (int j = i; j >= 0; j--)
            {
                int lo = max(0, j-1);
                int hi = min(j, i-1);
                buff[j] = min(buff[lo], buff[hi]) + triangle[i][j];
            }
        }
        int res = buff[0];
        for (int i = 1; i < len; i++)
            res = min(res, buff[i]);
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值