zoukankan      html  css  js  c++  java
  • [LeetCode]15. Pascal's Triangle杨辉三角

    Given numRows, generate the first numRows of Pascal's triangle.

    For example, given numRows = 5,
    Return

    [
         [1],
        [1,1],
       [1,2,1],
      [1,3,3,1],
     [1,4,6,4,1]
    ]

    杨辉三角主要有下列五条性质:

    1. 杨辉三角以正整数构成,数字左右对称,每行由1开始逐渐变大,然后变小,回到1。
    2. n行的数字个数为n个。
    3. n行的第k个数字为组合数C_{n-1}^{k-1}
    4. n行数字和为2^{n-1}
    5. 除每行最左侧与最右侧的数字以外,每个数字等于它的左上方与右上方两个数字之和(也就是说,第n行第k个数字等于第n-1行的第k-1个数字与第k个数字的和)。这是因为有组合恒等式:C_{n}^{i}=C_{n-1}^{i-1}+C_{n-1}^{i}

    解法1:根据杨辉三角的构造方法直接构造。

    class Solution {
    public:
        vector<vector<int>> generate(int numRows) {
            vector< vector<int> > res;
            for(int i = 0; i < numRows; i++)
            {
                vector<int> row(i + 1, 1);
                for(int j = 1; j < i; j++)
                    row[j] = res[i - 1][j - 1] + res[i - 1][j];
                res.push_back(row);
            }
            return res;
        }
    };

    解法2:杨辉三角的每一行的各元素即是组合数C(m,n),其中n表示第几行,m=0,1,...,n,使用公式C(m,n)=n!/m!/(n-m)!

    class Solution {
    public:
        vector<vector<int>> generate(int numRows) {
            vector< vector<int> > res;
            for(int i = 0; i < numRows; i++)
            {
                vector<int> row(i + 1, 1);
                for(int j = 0; j <= i; j++)
                    row[j] = fact(i) / fact(j) / fact(i - j);
                res.push_back(row);
            }
            return res;
        }
    private:
        long long fact(int n)
        {
            if(n <= 1)
                return 1;
            long long f = 1, res;
            for(int i = 2; i <= n; i++)
            {
                res = f * i;
                f = res;
            }
            return res;
        }
    };

    注意这个不能通过全部测试,原因在于numRows比较大时计算阶乘会溢出。考虑组合数计算的另外的公式C(m,n)=C(m-1,n-1)+C(m,n-1)可以改进:

    class Solution {
    public:
        vector<vector<int>> generate(int numRows) {
            vector< vector<int> > res;
            for(int i = 0; i < numRows; i++)
            {
                vector<int> row = getRow(i);
                res.push_back(row);
            }
            return res;
        }
    private:
        vector<int> getRow(int rowIndex) {
            vector<int> row;
            if (rowIndex < 0) 
                return row;
    
            row.assign(rowIndex + 1, 0);
            for (int i = 0; i <= rowIndex; ++i) 
            {
                if (i == 0) 
                {
                    row[0] = 1;
                    continue;
                }
                for (int j = rowIndex; j >= 1; --j) 
                    row[j] = row[j] + row[j - 1];
            }
            return row;
        }
    };

    这个方法效率比较差,因为为了计算第row行的数据,首先将第1行到第row-1行的所有数据都计算了一遍。

  • 相关阅读:
    bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
    CentOS 7下MySQL安装配置
    CentOS 7下设置DNS服务器
    MySQL Table is marked as crashed 解决方法
    supervisor使用
    Linux更改服务器Hostname
    在Linux中让打印带颜色的字
    php安装gearman扩展实现异步分步式任务
    GitLab的Gravatar头像服务不可用
    Nginx + tornado + supervisor部署
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4859217.html
Copyright © 2011-2022 走看看