杨辉三角问题(模拟/组合数)

简介: 杨辉三角问题(模拟/组合数)

LeetCode 118:输入行数numsRow,生成前numsRow的杨辉三角


示例:

输入: 5
输出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]


思路分析:根据杨辉三角分析:(1)两侧的值1(2)第n层有n个元素(3)非两侧元素 == 等于上一层竖直对应位置和其前一个位置的和。对于模拟填充分两步:


  • 边界填充1
  • 里边根据规则填充


代码实现:

class Solution {
    // 模拟填充
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ans = new ArrayList<>();
        for (int i = 0; i < numRows; i++) {
            List<Integer> level = new ArrayList<>();
            for (int j = 0; j <= i; j++) {
                if (j == 0 || j == i) {
                    level.add(1);
                } else {
                    List<Integer> tmp = ans.get(i - 1);
                    level.add(tmp.get(j) + tmp.get(j - 1));
                }
            }
            ans.add(level);
        }
        return ans;
    }
}


LeetCode 119:给定一个非负索引 k, k ≤ 33,返回杨辉三角的第 k 行。


示例:

输入: 3
输出: [1,3,3,1]


进阶:你可以优化你的算法到 O(k) 空间复杂度吗?


思路分析:这里基本思路是案例1相同,只不过返回某一行。


另外还可以使用公式法,将杨辉三角转化为组合数,如下图

image.png

组合公式


根据组合数的公式,将(n-k)!约掉,化简就是下边的结果。



代码实现:

class Solution {
    // 暴力解
    public List<Integer> getRow(int rowIndex) {
        List<List<Integer>> ans = new ArrayList<>();
        int i = 0;
        for (; i < rowIndex + 1; i++) {
            List<Integer> sub = new ArrayList<>();
            for (int j = 0; j <= i; j++) {
                if (j == 0 || j == i) {
                    sub.add(1);
                } else {
                    List<Integer> last = ans.get(i - 1);
                    sub.add(last.get(j - 1) + last.get(j));
                }
            }
            ans.add(sub);
        }
        return ans.get(i - 1);
    }
    // 组合数公式: 时间复杂度O(K^2)
    public List<Integer> getRow(int rowIndex) {
        List<Integer> ans = new ArrayList<>();
        int k = rowIndex;
        for (int i = 0; i <= k; i++) {
            ans.add(combination(k, i));
        }
        return ans;
    }
    // 计算组合数
    private int combination(int n, int k) {
        long ans = 1L;
        for (int i = 1; i <= k; i++) {
            ans = ans * (n - k + i) / i;
        }
        return (int) ans;
    }
    //组合数优化(pre记录之前算过的值)
    public List<Integer> getRow(int rowIndex) {
        List<Integer> ans = new ArrayList<>();
        long pre = 1L;
        int k = rowIndex;
        ans.add(1);
        for (int i = 1; i <= k; i++) {
            long cur = pre * (k - i + 1) / i;
            ans.add((int) cur);
            pre = cur;
        }
        return ans;
    }
}


相关文章
|
7月前
82: 求组合数
82: 求组合数
|
算法 测试技术 C++
C++二分算法习题:判断是否是完全平方数[容易]和排列箱子[容易]
C++二分算法习题:判断是否是完全平方数[容易]和排列箱子[容易]
|
7月前
|
算法 程序员
【算法训练-二分查找 四】【模拟二分】X的平方根
【算法训练-二分查找 四】【模拟二分】X的平方根
42 0
|
7月前
|
存储 C语言
牛客网刷题总结(1.有序序列判断,2.获得月份天数,3.矩阵相等判定,4.矩阵转换,5.井字棋判断输赢,6.递归进行进制转化)
牛客网刷题总结(1.有序序列判断,2.获得月份天数,3.矩阵相等判定,4.矩阵转换,5.井字棋判断输赢,6.递归进行进制转化)
76 0
|
算法 Python
【每周一坑】​计算100以内质数之和 +【解答】输出三角形
不过如果你有兴趣的话,可以进一步考虑一下你所用方法的算法复杂度是多少,看看谁的方法更简单。
|
Python
Python实现求取素数
Python实现求取素数
232 0
|
并行计算 C++
如何花式计算20的阶乘?
如何花式计算20的阶乘?
194 0