Leetcode | 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
[
[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.

这道题直接用dfs是过不了大数据的。所以大概也知道是用dp。

我想到的是从上往下,一维dp,v[i]表示到了第k层第i个位置的path最小值。

v[i]=min{v[i -1], v[i]}+triangle[k][i]。

如果从左往右扫,那么求完v[i]后,求v[i+1]时就用了新的v[i]值了,所以中间结果要用两个n维的vector来表示,一个用来表示上一层对应位置的path最小值。这个实现使用了和之前在做Word Ladder 类似的策略。

 1 class Solution {
 2 public:
 3     int minimumTotal(vector<vector<int> > &triangle) {
 4         int n = triangle.size();
 5         if (n == 0) return 0;
 6         
 7         vector<vector<int> > min(2, vector<int>(n, INT_MAX));
 8         int cur = 0, pre = 1;
 9         min[pre][0] = triangle[0][0];
10         
11         for (int i = 1; i < n; ++i) {
12             for (int j = 0; j < i + 1; ++j) {
13                 min[cur][j] = min[pre][j];
14                 if (j > 0 && min[pre][j - 1] < min[pre][j]) min[cur][j] = min[pre][j - 1];
15                 min[cur][j] += triangle[i][j];
16             }
17             pre = !pre;
18             cur = !cur;
19         }
20         
21         int m = min[pre][0];
22         for (int i = 1; i < n; ++i) {
23             if (min[pre][i] < m) m = min[pre][i];
24         }
25         
26         return m;
27     }
28 };

如果每一层从右往左扫,就不会有这个问题了,只要用一个n维的vector就够了。

 1 class Solution {
 2 public:
 3     int minimumTotal(vector<vector<int> > &triangle) {
 4         int n = triangle.size();
 5         if (n == 0) return 0;
 6         
 7         vector<int> min(n, INT_MAX);
 8         min[0] = triangle[0][0];
 9         
10         for (int i = 1; i < n; ++i) {
11             for (int j = i; j >= 1; --j) {
12                 if (min[j - 1] < min[j]) min[j] = min[j - 1];
13                 min[j] += triangle[i][j];
14             }
15             min[0] += triangle[i][0];
16         }
17         
18         int m = min[0];
19         for (int i = 1; i < n; ++i) {
20             if (min[i] < m) m = min[i];
21         }
22         
23         return m;
24     }
25 };

网上有从下往上扫的,于是也实现了一遍。不得不说这是更好的方式。从上往下的话,最后还要求最后一层的最小值。

初始值整个vector都设为0,最底层在求值的时候需要用到n+1个数,所以vector的大小为n+1。

 1 class Solution {
 2 public:
 3     int minimumTotal(vector<vector<int> > &triangle) {
 4         int n = triangle.size();
 5         if (n == 0) return 0;
 6         
 7         vector<int> min(n + 1, 0);
 8         
 9         for (int i = n - 1; i >= 0; --i) {
10             for (int j = 0; j <= i; ++j) {
11                 if (min[j + 1] < min[j]) min[j] = min[j + 1];
12                 min[j] += triangle[i][j];
13             }
14         }
15         
16         return min[0];
17     }
18 };
posted @ 2014-05-06 17:43  linyx  阅读(130)  评论(0编辑  收藏  举报