學會從后往前遍歷,例 [LeetCode] Pascal's Triangle II,劍指Offer 題4


當我們需要改變數組的值時,如果從前往后遍歷,有時會帶來很多麻煩,比如需要插入值,導致數組平移,或者新的值覆蓋了舊有的值,但舊有的值依然需要被使用。這種情況下,有時僅僅改變一下數組的遍歷方向,就會避免這些困難。

 

最直觀的一題是 劍指Offer上的面試題 4

另外一道例題,就是LeetCode上的 Pascal's Triangle II

Pascal's Triangle II

Given an index k, return the kth row of the Pascal's triangle.

For example, given k = 3,
Return [1,3,3,1].

Note:
Could you optimize your algorithm to use only O(k) extra space?

class Solution {
public:
    vector<int> getRow(int rowIndex) {
    }
};

 

所謂Pascal's Triangle,就是如下面所示的結構。

[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

要求O(k)空間復雜度的情況下,思路很直觀,就是先在vector<int> 存入 1,然后循環 k 次。偽代碼如下:

for(i = 0; i < k; ++i)
{
    v[0] = 1
    for(j = 1; j < k; ++j)
    {
        v[j] = v[j-1] + v[j];
    }
}

然而很快我發現這樣做是不對的,因為v[j]算出后,緊接着在j+1后的運算中會作為v[j-1]出現,也就是說,v[j-1]此時已經是新值了,不再是上一排的數,算出的結果將是錯誤的。

只要從v[1]開始往后遍歷,都會遇到這個問題。

那么我們改為 v[j] = v[j] + v[j+1],這樣確實可以避免值覆蓋問題,但是會出現 不得不整體移動數組的麻煩,因為前面算出的值沒法放了。

這個時候,如果轉而從最后一個值開始算起,逐漸算到v[1],就可以避開這個麻煩。

for(i = 0; i < k; ++i)
{
    v[k] = 1
    for(j = k-1; j > 0; --j)
    {
        v[j] = v[j-1] + v[j];
    }
    v[0] = 1;
}

 

代碼:

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> v;
        if(rowIndex < 0) return v;
        for(int i = 0; i <= rowIndex; ++i){
            v.push_back(0);
        }
        for(int j = 0; j <= rowIndex; ++j){
            v[rowIndex] = 1;
            for(int k = rowIndex-1; k > 0; --k){
                v[k] = v[k] + v[k-1];
            }
            v[0] = 1;
        }
        return v;
    }
};

Accepted  4ms 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM