Triangle

Triangle

  Total Accepted: 16109  Total Submissions: 60327 My Submissions

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.

思路1:搜索题,找出从顶到底路径中最小的和,则要在所有路径中即可行解中找出最优解。

直接用dfs查找TLE,因为有很多路径重复计算了。

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        if (triangle.empty()) return 0;
        ans = INT_MAX;
        dfs(triangle, 1, 0, triangle[0][0]);
        return ans;
    }
private:
    int ans;
    void dfs(vector<vector<int> > &triangle, int depth, int col, int sum) {
        // update solution
        if (depth == triangle.size()) {
            if (sum < ans)
                ans = sum;
            return;
        }
        dfs(triangle, depth + 1, col, sum + triangle[depth][col]);
        dfs(triangle, depth + 1, col + 1, sum + triangle[depth][col + 1]);
    }
};

思路2:为了避免重复计算,采用备忘录,用一个数组保存那个位置到底端的最优解。

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        if (triangle.empty()) return 0;
        for (int i = 0; i < triangle.size(); ++i) {
            memory.push_back(vector<int>(triangle[i].size(), INT_MAX));
        }
        return find(triangle, 0, 0);
    }
private:
    vector<vector<int> > memory;
    int find(vector<vector<int> > &triangle, int depth, int col) {
        if (memory[depth][col] != INT_MAX) {
            return memory[depth][col];
        }
        
        if (depth == triangle.size() - 1) {
            return memory[depth][col] = triangle[depth][col];
        }
        int left_sum = find(triangle, depth + 1, col);
        int right_sum = find(triangle, depth + 1, col + 1);
        
        int min_sum = min(left_sum, right_sum);
        min_sum += triangle[depth][col];
        
        return memory[depth][col] = min_sum;
    }
};

思路3:动态规划,从底向上,存储到低端的最优解,求解当前最优解时,只需用到下一层相邻节点的最优解。

方程:dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j] ( 0 <= i < max_depth-1)。

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        if (triangle.empty()) return 0;
        for (int i = 0; i < triangle.size(); ++i) {
            dp.push_back(vector<int>(triangle[i].size(), 0));
        }
        int depth = triangle.size() - 1;
        int col = 0;
        for ( ; col < triangle[depth].size(); ++col) {
            dp[depth][col] = triangle[depth][col];
        }
        for (depth = triangle.size() - 2; depth >= 0; --depth) {
            for (col = 0; col < triangle[depth].size(); ++col) {
                dp[depth][col] = min(dp[depth + 1][col], dp[depth + 1][col + 1]) + triangle[depth][col];
            }
        }
        return dp[0][0];
    }
private:
    vector<vector<int> > dp;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值