LeetCode 118. Pascal's Triangle

LeetCode 118. Pascal's Triangle_第1张图片
题目很简单,输入一个数字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;
}

你可能感兴趣的:(leetCode)