1. 程式人生 > >Leetcode 120. 三角形最小路徑和 C++

Leetcode 120. 三角形最小路徑和 C++

題目描述:

給定一個三角形,找出自頂向下的最小路徑和。每一步只能移動到下一行中相鄰的結點上。

例如,給定三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

自頂向下的最小路徑和為 11(即,3 + 1 = 11)。

說明:

如果你可以只使用 O(n) 的額外空間(n 為三角形的總行數)來解決這個問題,那麼你的演算法會很加分。

解答:

方法一:

空間複雜度O(n^{2}),但是在leetcode上執行時間只有了4ms,戰勝了99.92%的cpp提交者。我自己不是太懂為什麼方法一比方法二會快這麼多,因為迴圈都一樣的歷遍了元素,而且方法一還多了一個尋找最小值的迴圈。

方法一的思路是典型的動態規劃求法,是很容易想到的。用一個矩陣info來儲存到每一個點的最小值,分三種情況,

(1)如果元素在開頭,那麼 等於當前值加上它上一行對應的最小值。info[i][j]=triangle[i][j]+info[i-1][j]

(2)如果元素位於末尾,那麼等於當前值加上它上一行的最後一個元素。

(3)如果是在中間,那麼就要找上一行中能到達它的最小元素。

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int n=triangle.size();
        if(n==0) return 0;
        if(n==1) return triangle[0][0];
        vector<vector<int>> info(n,vector<int>(n,0));
        info[0][0]=triangle[0][0];
        for(int i=1;i<n;++i)
        {
            for(int j=0;j<=i;++j)
            {
                if(j==0) info[i][j]=triangle[i][j]+info[i-1][j];
                else if(j==i) info[i][j]=triangle[i][j]+info[i-1][j-1];
                else
                {
                    int temp=info[i-1][j]>info[i-1][j-1]?info[i-1][j-1]:info[i-1][j];
                    info[i][j]=temp+triangle[i][j];
                }
            }
        }
        int res=info[n-1][0];
        for(int i=0;i<n;++i)
        {
            if(info[n-1][i]<res)
            {
                res=info[n-1][i];
            }
        }
        return res;
    }
};

方法二:

空間複雜度O(n),執行用時52ms,比較慢。 

這種方法從最下面開始,向上尋找答案。只用一個長度為n的數列就可以儲存全部資訊。自下而上,計算完該層的最小值後,資訊不斷地在這個數列中更新,所以可以節省空間。

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int n=triangle.size();
        if(n==0) return 0;
        vector<int> info(n,0);
        for(int i=n-1;i>=0;--i)
        {
            for(int j=0;j<=i;++j)
            {
                if(i==n-1) info[j]=triangle[i][j];
                else
                {
                    int temp=(info[j]>info[j+1])?info[j+1]:info[j];
                    info[j]=triangle[i][j]+temp;
                }
            }
        }
        return info[0];
        
    }
};

參考: