zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    TOJ1017: Tour Guide
    tzcacm去年训练的好题的AC代码及题解
    Educational Codeforces Round 40 (Rated for Div. 2)
    AtCoder Regular Contest 092
    浙南联合训练赛20180318
    [Offer收割]编程练习赛50
    牛客练习赛13
    AtCoder Regular Contest 091
    Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)
    csa Round #73 (Div. 2 only)
  • 原文地址:https://www.cnblogs.com/linyx/p/3712086.html
Copyright © 2011-2022 走看看