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.

 

方法一:

数组f,f[i,j] 表示从(0,0)到(i,j)的路径最小和,然后比较最后一行的最小值。top to down方法

 

 1 class Solution {
 2     public:
 3     // form top to down
 4     int minimumTotal(vector<vector<int> > &triangle) {
 5 
 6         size_t rowNum = triangle.size();
 7         if(rowNum == 0)
 8             return 0;
 9 
10         vector<vector<int> >f(rowNum);
11 
12         for(size_t i = 0 ; i< rowNum; i++)
13         {
14             f[i].resize(i+1, 0);
15         }   
16 
17         for(size_t i = 0 ; i< rowNum; i++)
18         {   
19             //printVector(triangle[i]);
20         }   
21 
22     
23         f[0][0] = triangle[0][0];
24         for(size_t i = 1 ; i< rowNum; i++)
25         {   
26             for(size_t j = 0; j <= i; j++)
27             {   
28                 if(j == 0)
29                     f[i][j] = f[i-1][j] + triangle[i][j];
30                 else if(j == i)
31                     f[i][j] = f[i-1][j-1] + triangle[i][j];
32                 else
33                 {
34                     int a = INT_MAX;
35                     if(i-1 >= 0 && j-1 >= 0 && j <= i)
36                         a = f[i-1][j-1];
37                     int b = INT_MAX;
38                     if(i-1 >= 0 && j >= 0 && j <= i-1)
39                         b = f[i-1][j];
40                     f[i][j] = min(a, b) + triangle[i][j];
41                 }
42             }
43         }
44 
45         int res = INT_MAX;
46         for(size_t i = 0 ; i< rowNum; i++)
47         {
48            // printVector(f[i]);
49             res = min(res, f[rowNum-1][i]);
50         }
51 
52         return res;
53     }
54 };

 

 

方法二:

bottom up方法,少了很多边界判断,f也可以只保留一行,随时更新

 1     int minimumTotal(vector<vector<int> > &triangle) {
 2 
 3         size_t rowNum = triangle.size();
 4         if(rowNum == 0)
 5             return 0;
 6 
 7         vector<vector<int> >f(rowNum);
 8 
 9         for(size_t i = 0 ; i< rowNum; i++)
10         {   
11             f[i].resize(i+1, 0); 
12         }   
13 
14         for(size_t i = 0 ; i< rowNum; i++)
15         {   
16             f[rowNum-1][i] = triangle[rowNum-1][i];
17         }   
18             
19         for(size_t i = rowNum-2 ; i >= 0; i--)
20         {   
21             for(size_t j = 0; j <= i; j++)
22             {   
23                 int a = f[i+1][j];
24                 int b = f[i+1][j+1];
25                 f[i][j] = min(a, b) + triangle[i][j];
26             }
27         }
28 
29         return f[0][0];
30     }

 

方法三: 在原地的数组进行运算,节省了空间

 1 class Solution {
 2     public:
 3     int minimumTotal(vector<vector<int> > &f) {
 4 
 5         size_t rowNum = f.size();
 6 
 7             
 8         for(size_t i = rowNum-2 ; i >= 0; i--)
 9         {   
10             for(size_t j = 0; j <= i; j++)
11             {   
12 
13                 int a = f[i+1][j];
14                 int b = f[i+1][j+1];
15                 f[i][j] = min(a, b) + f[i][j];
16             }
17         }
18 
19         return f[0][0];
20     }
21 }