題目地址:
- https://leetcode-cn.com/problems/pascals-triangle/ 楊輝三角 I
- https://leetcode-cn.com/problems/pascals-triangle-ii/ 楊輝三角 II
題目內容:
在楊輝三角中,每個數是他的左上方和右上方的數的和,公式表達爲:
題目內容:
- 楊輝三角 I: 給定一個非負整數 numRows,生成楊輝三角的前 numRows 行。
示例:
輸入: 5
輸出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
這題最直觀的方法是採用遞推式(1),根據上一行的數據直接產生下一行的數據就行了,比較簡單,見代碼:
class Solution {
public:
vector<vector<int>> generate(int numRows) {
// f(i,j) = f(i-1, j-1)+f(i-1,j)
if (numRows <= 0)
return vector<vector<int>>();
vector<vector<int>> ret;
ret.push_back(vector<int>{1});
for(int layer = 1; layer < numRows; layer++){
vector<int> tmp(layer+1);
tmp[0] = 1;
tmp[layer] = 1;
for (int element = 1; element < layer; element++)
tmp[element] = ret[layer-1][element-1]+ret[layer-1][element];
ret.push_back(tmp);
}
return ret;
}
};
容易知道,此代碼的時間複雜度是,空間複雜度爲
如果我們輸入行數,只需要函數輸出特定行數的排列,而不需要整個前n行的排列,我們可以怎麼做呢?當然,我們可以把前n行都計算出來後,取某個行的結果,不過這樣的計算複雜度是比較高的,我們可以用一些巧妙些的方法,把計算複雜度和空間複雜度減少,見第二題。
題目內容:
- 楊輝三角II:給定一個非負索引 k,其中 k ≤ 33,返回楊輝三角的第 k 行
示例:
輸入: 3
輸出: [1,3,3,1]
注意到我們可以把第二題的空間複雜度優化到,針對指定的第n行,我們只需要線性空間即可。算法流程如下:我們首先初始化出一個數組,這個數組的長度爲n+1
,對於任意行,總是可以把第一個數初始化爲1,假設我們的n=4,於是我們有初始化的數組[1,0,0,0]
,我們有如下遞推公式:
for (int i = n-1; i > 0; --i)
v[i] = v[i]+v[i-1];
我們發現,其實是倒過來進行相鄰元素疊加的,因爲如果是正向疊加,會影響到之前的元素,操作起來比較麻煩些,而倒過來進行則不會這樣。於是有:
第一輪
step1: [1, 0, 0, 0] 初始化
step2: [1, 0, 0, 0] 空操作
step3: [1, 0, 0, 0] 空操作
step4: [1, 1, 0, 0]
第二輪
step1: [1, 1, 0, 0] 空操作
step2: [1, 2, 1, 0]
我們注意到有部分0+0
的操作是空操作,是不必要的,可以去掉以提高性能。最終,我們的代碼如下所示:
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> ret(rowIndex+1);
ret[0] = 1;
for (int j = rowIndex; j > 0; j--)
for (int i = rowIndex-j+1; i > 0; --i)
ret[i] += ret[i-1];
return ret;
}
};
還算是比較精簡的,其時間複雜度爲,準確的說是,空間複雜度爲。
容易出現的問題:
- 注意邊界,爲了減少空操作,邊界特別要注意。