力扣-119. 杨辉三角 II

1.题目

题目地址(119. 杨辉三角 II - 力扣(LeetCode))

https://leetcode.cn/problems/pascals-triangle-ii/

题目描述

给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

 

示例 1:

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

示例 2:

输入: rowIndex = 0
输出: [1]

示例 3:

输入: rowIndex = 1
输出: [1,1]

 

提示:

  • 0 <= rowIndex <= 33

 

进阶:

你可以优化你的算法到 O(rowIndex) 空间复杂度吗?

2.题解

2.1 滚动数组

思路

针对118中使用二维数组进行了较小优化,只保存当前层和上一层的数据

代码

  • 语言支持:C++

C++ Code:


class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> prev, cur;
        for(int i = 0; i <= rowIndex; i++){
            cur.resize(i + 1);
            cur[0] = cur[i] = 1;
            for(int j = 1; j < i; j++){
                cur[j] = prev[j] + prev[j-1];
            }
            prev = cur;
        }
        return cur;
    }
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:\(O(rowIndex^2)\)
  • 空间复杂度:\(O(n)\)

2.2 一个数组(倒算)

思路

简化空间复杂度为O(1)? 如何实现?
我们思考 row[i][j] = row[i-1][j] + row[i-1][j-1];
在由第i-1行到第i行的过程中, 我们能否直接根据该层状态进行原地更新?
从前向后更新肯定是不行的, 由于每次计算 row[j] = row[j] + row[j-1] 中需要利用到j-1, 但是我们刚计算完前面的值就将其覆盖掉了
那我们思考,能否进行倒算呢?从该行本来应该的最后一个位置向前倒算即可!!!

代码

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> row(rowIndex + 1);
        row[0] = 1;
        for(int i = 1; i <= rowIndex; i++){
            for(int j = i; j > 0; j--){
                row[j] += row[j - 1];// 由于公式是row[i-1][j] + row[i-1][j-1], 需要用到前面一行的数据,从后向前加就不会覆盖数据了,而且随着i增大,不断扩展个数
            }
        }

        return row;
    }
};

2.3 数学公式(线性递推)

思路

根据杨辉三角的性质可知, 每层的每个元素其实就是 \(C^m_n\)
对于组合数公式, 只要直到其中一个就可以地推出所有的项, 推导如下:

代码

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> row(rowIndex + 1);
        row[0] = 1;
        for(int i = 1; i <= rowIndex; i++){
            row[i] = row[i-1] * (rowIndex - i + 1) / i;
        }

        return row;
    }
};
``
posted @ 2024-04-25 23:01  DawnTraveler  阅读(8)  评论(0编辑  收藏  举报