120. Triangle - LeetCode

?题目描述

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

例如,给定三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

说明:

如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

 

 ?Method 1: DP

class Solution {
public:
    // [[2],               [[2],
    //  [3,4],              [5,6],
    //  [6,5,7],            [11,10,11],
    //  [4,1,8,3]]          [15,11,18,14]]
    int minimumTotal(vector<vector<int>>& triangle) {
        int n = triangle.size();
        // ans_[i][j] = minTotalOf(i,j)
        // ans_[i][j] = min(ans_[i-1][j],ans_[i-1][j-1]) + triange[i-1][j-1]
        // ↓为了好操作,给二维数组加个padding 从1->n,所以 ans_[i][j]对应triange[i-1][j-1]
        ans_ = vector<vector<int>>(n + 1, vector<int>(n + 1, INT32_MAX));//因为要求最小的total所以就设置成最大值,也就是边界
        for (int i = 1; i <= n ; ++i) {
            for (int j = 1; j <= i; ++j) {
                ans_[i][j] = triangle[i-1][j-1];
                if (i == 1) continue;
                else if (j == 1) ans_[i][j] += ans_[i - 1][j];
                else if (j == i) ans_[i][j] += ans_[i - 1][j - 1];
                else ans_[i][j] += min(ans_[i - 1][j], ans_[i - 1][j - 1]);
            }
        }
        return *min_element(ans_[n].begin(), ans_[n].end());
    }
private:
    vector<vector<int>> ans_;
};

?Method 2: DP,因为发现每次只会访问上一行元素,所以没有必要保留这么多行,只需要保留两行就行了,也就是滚动数组(swap使用)。

class Solution {
public:
    // [[2],               [[2],
    //  [3,4],              [5,6],
    //  [6,5,7],            [11,10,11],
    //  [4,1,8,3]]          [15,11,18,14]]
    int minimumTotal(vector<vector<int>>& triangle) {
        int n = triangle.size();
        // ans_[i][j] = minTotalOf(i,j)
        // ans_[i][j] = min(ans_[i-1][j],ans_[i-1][j-1]) + triange[i-1][j-1]
        // ↓为了好操作,给二维数组加个padding 从1->n,所以 ans_[i][j]对应triange[i-1][j-1]
        ans_ = vector<vector<int>>(2, vector<int>(n + 1, INT32_MAX));//因为要求最小的total所以就设置成最大值,也就是边界
        for (int i = 1; i <= n ; ++i) {
            for (int j = 1; j <= i; ++j) {
                ans_[1][j] = triangle[i-1][j-1];
                if (i == 1 && j == 1) continue;
                if (j == 1) ans_[1][j] += ans_[0][j];
                else if (j == i) ans_[1][j] += ans_[0][j - 1];
                else ans_[1][j] += min(ans_[0][j], ans_[0][j - 1]);
            }
            swap(ans_[0], ans_[1]);
        }
        return *min_element(ans_[0].begin(), ans_[0].end());
    }
private:
    vector<vector<int>> ans_;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值