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?
关键还是杨辉三角的性质:每个数字等于上一行的左右两个数字之和,即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和
思路一:第n行的第m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数,且第m个数和第n-m+1个数相等,因此可以根据该公式计算出来特定行的每个元素
代码实现:
vector<int> getRow_limit(int rowIndex) //rowIndex从0开始计数
{
//第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数,且第m个数和第n-m+1个数相等
int i = 0, j = rowIndex;
int k, temp_top, temp_down , mul_top, mul_down;
vector<int> output(rowIndex + 1);
while (i <= j)
{
mul_top = mul_down = 1;//每次计算前要先初始化
if (i == 0)
mul_top = mul_down = 1;
else
{
for (k = 0; k < i; k++) //计算C (rowIndex i),i代表分母有几个元素相乘
{
temp_top = rowIndex - k;
mul_top *= temp_top;//计算分子
temp_down = k+1;
mul_down *= temp_down;
}
}
output[i] = output[j] = mul_top / mul_down;
i++;
j--;
}
return output;
}
这种实现的问题在于当rowIndex比较大的时候会因为int的长度不够而越界,从而计算出错误的结果(提交的时候当rowIndex=18的时候中间的那个元素出来的结果就是错的了…..)
于是把while循环里面的语句稍微修改了一下,如下:
while (i <= j)
{
mul_top = mul_down = 1;//每次计算前要先初始化
if (i == 0)
mul_top = mul_down = 1;
else
{
for (k = 0; k < i; k++) //计算C (rowIndex i),i代表分母有几个元素相乘
{
temp_top = rowIndex - k;
mul_top *= temp_top;//计算分子
temp_down = k + 1;
mul_top /= temp_down;
}
}
output[i] = output[j] = mul_top;
i++;
j--;
}
和上面的实现相比稍微好了一些,但是当数字过大的时候还是会出现同样的问题(提交的时候当rowIndex=30的时候有错…
思路二:参考别人的代码,觉得思路确实很巧妙,而且没有开辟额外的空间,先贴代码
代码实现:
vector<int> getRow(int rowIndex) //rowIndex从0开始计数
{
int row,col;
vector<int> output(rowIndex + 1,0);
output[0]=1;//第一个元素初始化为1
for(row=0;row<=rowIndex;row++)
{
for(col=row;col>=1;col--)
{
output[col]=output[col]+output[col-1];//每行从后往前计算,利用杨辉三角的性质,第n行的第i个元素等于第n-1行的第i个和第i-1个元素之和
}
}
return output;
}
这里的实现是先根据rowIndex确定要返回的vector的长度,然后也是利用杨辉三角的性质一行一行的进行计算,而且每行是从末尾的元素开始计算的.
例如n=5,当计算到第3行时,vector里面存放的依次是[1 2 1 0 0],计算第4行的时候首先计算最后一个元素output[3]=output[3]+output[2],因为上一行的元素已经按顺序存放在output前面,所以直接这样引用即可,不过要注意output[3]此时还没有计算,所以默认值应该置为0,而每行的第一个数一定是1,也就是代码中一开始就初始化的output[0]=1,因此循环的时候让col>=1就行了.
这样计算下来就ok了~~,相比于输出整个杨辉三角,时间复杂度是一样的,但是空间复杂度要小很多..