题目很简单,输入一个数字n,返回一个n行的杨辉三角。
解题思路也很简单,我们知道杨辉三角的第n+1行第m+1列的元素为c(n,m)=n!/[m!(n-m)!]。所以我们写个一个函数可以返回c(n,m),再利用两重循环就可以填充这个杨辉三角了(可以看作一个二维矩阵)。
我也是这么做的,写了一个函数先求n!,再求m!,(n-m)!,最后返回n!/[m!(n-m)!]。注意这里要考虑n=0,m=0以及n=m时的情况。但提交之后却发现WA。debug之后发现当n,m较大时,虽然c(n,m)最终不大,但中途出现的n!,m!会很大,会越界导致数据出错。所以我把原先的int改成long long。但还是不够大,不足以通过所有测试样例。
于是我只能再改进,我把n!/[m!(n-m)!]约分成(n-m+1)*…*n/m!。这样的话当m较小时,这个数就不会在中途出现很大的数。
比如说c(25,1)= 25/1。但如果m较大时c(25,24) = 2*3*…*25/24!,依然会出现越界的问题。这里我们就要利用组合排列中c(n,m) = c(n,n-m)的性质使得这里的m始终是较小的。
AC代码:
int num(int n,int m){
if(n==0 || n == m || m == 0)
return 1;
else if(m>n/2)
return num(n,n-m);
else{
long long tempM,tempM_N;
tempM = tempM_N = 1;
for(int i = n-m+1;i <= n;i++){
tempM_N*=i;
}
for(int i = 1;i <= m;i++){
tempM*=i;
}
return tempM_N/tempM;
}
}
vector<vector<int> > generate(int numRows) {
vector<vector<int> > ans;
for(int i = 1;i <= numRows;i++){
vector<int> row;
for(int j = 1;j <= i;j++){
row.push_back(num(i-1,j-1));
}
ans.push_back(row);
}
return ans;
}