120. Triangle

Problem Statement: 

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.

Solution one(NOT AC): 

Divide and conquer

It is constructed in a triangle shape, however, it is a tree, but, eahc node is connectd by two node of it`s upper level except the left and right end.

For each node, we get the minimum from it`s left and right children, and goes on until it reach the next level of all leaf node.

 1 class Solution {
 2 public:
 3     // divide && conquer solution
 4     int FindMinPathSum(int i, int j, vector<vector<int>>& triangle){
 5         // termination condition
 6         // no any value, nothing to add to the final value.
 7         if (i == triangle.size()) {
 8             return 0;
 9         }
10         return min(FindMinPathSum(i + 1, j, triangle), FindMinPathSum(i + 1, j + 1, triangle)) + triangle[i][j];
11     }
12     int minimumTotal(vector<vector<int>>& triangle) {     
13         return FindMinPathSum(0, 0, triangle);
14     }
15 };

Solution one follow up:

Dynamic programming

However, this is not an accepted solution in Leetcode since it is time limited exceeded.

Each node is connected with two upper level nodes, for this node, we need do two times dfs to find the solution, it is duplicated.

The solution is to keep a hash table or the same two dimension array with original triangle, it stores the optimal solution, if it existes, return, no need to do iteration.

I give the Solution two, it is an accepted solution(AC):

 1 class Solution {
 2 public:
 3     // dynamic programming
 4     int FindMinPathSum(int i, int j, vector<vector<int>>& hash_table, vector<vector<int>>& triangle){
 5         // termination condition
 6         // no any value, nothing to add to the final value.
 7         if (i == triangle.size()) {
 8             return 0;
 9         }
10         if(hash_table[i][j] != INT_MAX){
11             return hash_table[i][j];
12         } else {
13             hash_table[i][j] = min(FindMinPathSum(i + 1, j, hash_table, triangle), FindMinPathSum(i + 1, j + 1, hash_table, triangle)) + triangle[i][j];
14             return hash_table[i][j];
15         }
16     }
17     int minimumTotal(vector<vector<int>>& triangle) {
18         // initialize the hash table to store the optimal solution for current node
19         // to avoid duplicated dfs
20         vector<vector<int>> hash_table;
21         vector<int> one_level;
22         for(int row = 0; row < triangle.size(); row++){
23             one_level.clear();
24             for(int col = 0; col < triangle[row].size(); col++){
25                 one_level.push_back(INT_MAX);
26             }
27             hash_table.push_back(one_level);
28         }
29         return FindMinPathSum(0, 0, hash_table, triangle);
30     }
31 };

Solution three(AC):

It is a bottom to top, it is pretty easy to understand, we should start from the last two level to loop, the code is as following:

 1 class Solution {
 2 public:
 3     int minimumTotal(vector<vector<int>>& triangle) {
 4         for(int i = triangle.size()-2; i>=0; i--){
 5             for(int j = 0; j<triangle[i].size(); j++){
 6                 triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]);
 7             }
 8         }
 9         return triangle[0][0];
10     }
11 };

Solution four(AC):

It is a top to bottom solution, we start to loop from second row and do boundary check for the first and last element in each row. The code is as following:

 1 class Solution {
 2 public:
 3     // top to bottom 
 4     int minimumTotal(vector<vector<int>>& triangle) {
 5         for(int i = 1; i < triangle.size(); i++){
 6             for(int j = 0; j < triangle[i].size(); j++){
 7                 // boundary check
 8                 // the minimum path sum of the first element in each row
 9                 if (j == 0) {
10                     triangle[i][j] += triangle[i - 1][0];
11                 } else if (j == triangle[i].size() - 1) {
12                     // the minimum path sum of the last element in each row
13                     triangle[i][j] += triangle[i - 1][j - 1];
14                 } else {
15                     // other elements
16                     triangle[i][j] += min(triangle[i - 1][j - 1], triangle[i - 1][j]);
17                 }
18             }
19         }
20         int last_row_idx = triangle.size() - 1;
21         int min_path_sum = INT_MAX;
22         // find the minimum value of last row
23         for(int i = 0; i < triangle[last_row_idx].size(); i++){
24             min_path_sum = min(min_path_sum, triangle[last_row_idx][i]);    
25         }
26         return min_path_sum;
27     }
28 };
原文地址:https://www.cnblogs.com/wdw828/p/6414693.html