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的数据,然后将他们复制到后面即可。优化的代码这里就不再给出了(因为我懒_

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