ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】力扣119.杨辉三角Ⅱ

2021-02-16 13:32:16  阅读:148  来源: 互联网

标签:int 题解 复杂度 List 力扣 rowIndex 杨辉三角 new row


题目来源

119. 杨辉三角 II

思路

方法一

杨辉三角的性质:

  1. 每行数字左右对齐,由1开始逐渐变大再变小,并最终回到1.
  2. 第\(n\)行(从\(0\)开始编号)的数字有\(n+1\)项,前\(n\)行共有\(\frac{n(n+1)}{2}\)个数。
  3. 第\(n\)行的第\(m\)个数(从\(0\)开始编号)可表示为可以被表示为组合数\(C(n,m)\),记作\(C_{n}^{m}\)或 \(\binom{n}{m}\),即为从n个不同元素中取m个元素的组合数。我们可以用公式来表示它:\(C_n^m = \frac{n!}{m!(n−m)!}\)
  4. 每个数字等于上一行的左右两个数字之和,可用此性质写出整个杨辉三角。即第n行的第i个数等于第n-1行的第i-1个数和第i个数之和。即\(C_n^i=C_{n-1}^i+C_{n-1}^{i-1}\)。
  5. \((a+b)^n\)的展开式(二项式展开)中的各项系数一次对应杨辉三角的第\(n\)行中的每一项。

递推:

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<List<Integer>> C = new ArrayList<List<Integer>>();
        for (int i = 0; i <= rowIndex; ++i) {
            List<Integer> row = new ArrayList<Integer>();
            for (int j = 0; j <= i; ++j) {
                if (j == 0 || j == i) {
                    row.add(1);
                } else {
                    row.add(C.get(i - 1).get(j - 1) + C.get(i - 1).get(j));
                }
            }
            C.add(row);
        }
        return C.get(rowIndex);
    }
}

优化

用滚动数组的思想,优化空间复杂度。

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<Integer> pre = new ArrayList<Integer>();
        for (int i = 0; i <= rowIndex; ++i) {
            List<Integer> cur = new ArrayList<Integer>();
            for (int j = 0; j <= i; ++j) {
                if (j == 0 || j == i) {
                    cur.add(1);
                } else {
                    cur.add(pre.get(j - 1) + pre.get(j));
                }
            }
            pre = cur;
        }
        return pre;
    }
}

进一步优化

动态规划+滚动数组优化,只用一个数组,从后往前(从右往左)更新

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<Integer> row = new ArrayList<Integer>();
        row.add(1);
        for (int i = 1; i <= rowIndex; ++i) {	// 外循环,遍历行数
            row.add(0);
            for (int j = i; j > 0; --j) {	// 内循环,从右边往左边遍历,利用滚动数组优化
                row.set(j, row.get(j) + row.get(j - 1));
            }
        }
        return row;
        // 另一种写法:
        // Integer[] dp = new Integer[rowIndex+1];
        // Arrays.fill(dp,1);
        // for(int i = 2;i<dp.length;i++){
        //     for(int j = i-1;j>=0;j--){
        //         dp[j] = dp[j] + dp[j-1];
        //     }
        // }
        // List<Integer> res = Arrays.asList(dp);
        // return res;
    }
}

复杂度分析

  1. 时间复杂度:\(O(rowIndex^2)\)。
  2. 空间复杂度:\(O(1)\)。不考虑方绘制的空间占用。

方法二

线性递推。由组合数公式\(C_n^m = \frac{n!}{m!(n-m)!}\),可以得到同一行的相邻组合数的关系

\[C_n^m = C_n^{m-1} × \frac{n-m+1}{m} \]

由于\(C_n^0 = 1\),利用上述公式我们可以在线性时间计算出第\(n\)行的所有组合数。

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<Integer> row = new ArrayList<Integer>();
        row.add(1);
        for (int i = 1; i <= rowIndex; ++i) {
            row.add((int) ((long) row.get(i - 1) * (rowIndex - i + 1) / i));
        }
        return row;
    }
}

复杂度分析

  • 时间复杂度:\(O(rowIndex)\)。
  • 空间复杂度:\(O(1)\)。不考虑返回值的空间占用。

参考来源

  1. 力扣官方题解:杨辉三角Ⅱ

标签:int,题解,复杂度,List,力扣,rowIndex,杨辉三角,new,row
来源: https://www.cnblogs.com/zzzzzy2k/p/14406524.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有