zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    案例19-页面使用ajax显示类别菜单
    案例18-首页最新商品和热门商品显示
    案例17-validate自定义校验规则校验验证码是否输入正确
    案例16-validate自定义校验规则校验用户名是否存在
    案例15-基本的表单校验使用validate
    测开之路六十九:监控平台之视图层
    测开之路六十八:监控平台之监控逻辑和处理逻辑
    测开之路六十七:监控平台之附加功能准备
    测开之路六十六:UI测试平台之处理逻辑和蓝图添加到程序入口
    测开之路六十五:UI测试平台之js
  • 原文地址:https://www.cnblogs.com/wdw828/p/6414693.html
Copyright © 2011-2022 走看看