您的位置:首页 > 其它

LeetCode 119. Pascal's Triangle II

2016-05-24 15:33 459 查看


题目很简单,输入一个数字n,返回杨辉三角的第n行。(他这里使用的是0 1 2 3这种计数来表示行数,就比如他给的例子k=3,返回的是1 3 3 1)

杨辉三角:

1

1 1

1 2 1

1 3 3 1

……

解题思路和上一篇博客(LeetCode 118. Pascal’s Triangle

http://blog.csdn.net/trident_/article/details/51490228)基本一致,我们知道杨辉三角的第n+1行第m+1列的元素为c(n,m)。所以我们写个一个函数可以返回c(n,m),再利用一重循环就可以杨辉三角的第n行了。

上篇博客说到我的改进,我把n!/[m!(n-m)!]约分成(n-m+1)*…*n/m!。这样的话当m较小时,这个数就不会在中途出现很大的数。

但这个改进到这题还不够通过所有样例,还是会越界(k=30时),于是我再改进,我不分开计算(n-m+1)*…*n和m!,而是在一个循环之中完成计算,即在一个循环中既有乘法也有除法,因为m一定小于n-m(详见上篇博客,上面有给链接),所以我以n-m+1~n为循环的范围。用temp表示分母,一开始temp = m,每次计算后temp-1,直到temp == 1。这样中途就基本不可能出现较大的数了。

(不清楚这段的可以结合后面的代码来理解,talk is cheap,show me the code)

但要注意原先的longlong类型要改为double类型。因为涉及到除法,不一定是整数类型。

但这样提交还是WA,到k=15时有几个数和标准答案差了1,我感觉是double类型一直除不尽,误差一直存在,甚至越来越大,而到后面我返回的是int类型,结果就四舍五入什么的导致有了1的误差。我只得尝试把分母由m减到1改成从1加到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{
double tempM_N,temp;
tempM_N = 1;
temp = 1;
for(int i = n-m+1;i <= n;i++){
tempM_N*=i;
if(temp <= m){
tempM_N/=temp;
temp++;
}

}
return tempM_N;
}

}
vector<int> getRow(int rowIndex) {
vector<int> ans;
for(int i = 1; i <= rowIndex+1;i++){
ans.push_back(num(rowIndex,i-1));
}
return ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: