【LeetCode】120

原题: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.

相似修改:Number Triangle
Time limit: 1 second Memory limit: 64MB
Problem Description
Consider the number triangle shown below. Write a program that calculates the highest sum of numbers that can be passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.

    7

   3 8

  8 1 0

 2 7 4 4

4 5 2 6 5

In the sample above, the route from 7 to 3 to 8 to 7 to 5 produces the highest sum: 30.

Input Description
There are multiple test cases. The first line of each test case contains R (1 <= R <= 1000), the number of rows. Each subsequent line contains the integers for that particular row of the triangle. All the supplied integers are non-negative and no larger than 100.

Output Description
Print a single line containing the largest sum using the traversal specified for each test case.

Sample Input
5
     7
   3 8
  8 1 0
 2 7 4 4
4 5 2 6 5

Sample Output
30

下面给出原题的解法:

解法一:从上往下遍历,时间复杂度为O(n^2),且需要处理每行的头和尾

1 class Solution {
 2 public:
 3     int minimumTotal(vector<vector<int> > &triangle) {
 4         vector<vector<int>> temp(triangle);
 5         vector<vector<int>>::size_type length=temp.size();    
 6         int i,j;
 7         for(i=1;i<length;i++){  
 8             vector<int>::size_type length_inner = temp[i].size();  
 9             for(j=0;j<length_inner;j++){  
10                 if(j == 0){  
11                     temp[i][j] = temp[i][j] + temp[i-1][j];  
12                 }else if(j == length_inner - 1){  
13                     temp[i][j] = temp[i][j] + temp[i-1][j-1];  
14                 }else{  
15                     temp[i][j] = (temp[i][j] + temp[i-1][j-1] < temp[i][j] + temp[i-1][j] ? temp[i][j] + temp[i-1][j-1]:temp[i][j] + temp[i-1][j]);  //求和最大的路径即'<'改成'>'
16                 }  
17             }  
18         }
19         int min = temp[length-1][0];  
20         for(i=1;i<temp[length-1].size();i++){  
21             min = (min < temp[length-1][i]?min:temp[length-1][i]);  //求和最大的仅做相应简单修改
22         }  
23         return min;
24     }
25 };

解法二:从下往上遍历,从倒数第二行开始计算每个元素与下一行与它相邻的两个元素的和,比较并保存最小值,最后triangle[0][0]即为结果

#include<iostream>
#include<vector>
using namespace std;

int maxmumTotal(vector<vector<int>> &triangle)
{
    vector<vector<int>> temp(triangle);
    for(int i=temp.size()-2;i>=0;i--)
    {
        for(int j=0;j<temp[i].size();j++)
        {
            temp[i][j]+=min(temp[i+1][j],temp[i+1][j+1]);
        }
    }
    return temp[0][0];
}

int main()
{
    int n = 0;
    while (cin >> n)
    {
        vector<vector<int>> tree;
        for (int i = 0; i < n; ++i)
        {
            vector<int> row;
            for (int j = 0; j <= i; ++j)
            {
                int temp = 0;
                cin >> temp;
                row.push_back(temp);
            }
            tree.push_back(row);
        }
        cout<<maxmumTotal(tree);
    }    
    system("pause");
}
原文地址:https://www.cnblogs.com/irun/p/4506878.html