LeetCode之遞歸——楊輝三角

鏈接:楊輝三角
描述:

給定一個非負整數 numRows,生成楊輝三角的前 numRows 行。比如給定5,則生成以下數組。

                  1
             1       1
         1       2       1
      1     3        3        1
   1    4       6       4      1
1      5    10      10     5     1

思路:

既然是講遞歸,那麼就先尋找規律。根據楊輝三角的定義,很容易的知道第n行和第n+1行元素之間的關係——假設低n行的數據爲f(n),f(n,x)爲第n行的x個元素,則f(n+1,x) = f(n,x-1) + f(n,x)。可以很容易的想到通過遞歸得到任意行的數據,之後只要遍歷n遍即可得到想要的楊輝三角了。代碼如下:

class Solution {
public:
	// 生成楊輝三角
	vector<vector<int>> generate(int numRows) {
		vector<vector<int>> ret;
		
		for (size_t i = 0; i < numRows; i++)
		{
			ret.push_back(getLine(i+1));
		}
		return  ret;
	}

	// 得到楊輝三角中指定行的數據
	vector<int> getLine(int row)
	{
		vector<int> ret;
		for (size_t i = 0; i < row; i++)
		{
			if (i == 0 || i == row - 1)
			{
				ret.push_back(1);
				continue;
			}

			vector<int> vLast = getLine(row - 1);
			int nValue = vLast[i - 1] + vLast[i];
			ret.push_back(nValue);
		}

		return ret;
	}
};

問題:

雖然很容易的解決了問題,但是這裏存在一個弊端,就是運行超時。因爲當爲了獲取f(n+1)的數據時,它會先獲取f(n),但是f(n)又依賴於f(n-1),這樣當爲了 得到f(5)的數據,f(4)被調用2次,f(3)被調用4次,f(2)被調用8次,造成時間和空間上成指數的開銷。爲了解決這個問題,非遞歸實現是一個更好的選擇。

非遞歸實現

	vector<vector<int>> generate(int numRows) {
		vector<vector<int>> ret;
		
		for (size_t i = 0; i < numRows; i++)
		{
			vector<int> row;
			for (size_t k = 0; k < i + 1; k++)
			{
				if (k == 0 || k == i)
				{
					row.push_back(1);
					continue;
				}
				row.push_back(ret[i - 1][k - 1] + ret[i - 1][k]);
			}

			ret.push_back(row);
		}
		return  ret;
	}

這個解法大比遞歸不管是時間還是空間複雜度都降低了很多,但其實還可以做進一步的優化。仔細觀察,楊輝三角的每一行都是對稱的,此時只需要獲取f(n)中的0~n/2+1的數據,然後將他們複製到後面即可。優化的代碼這裏就不再給出了(因爲我懶_

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章