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 };