Easy
题目描述
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。
示例 1:
输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
示例 2:
输入: numRows = 1
输出: [[1]]
提示:
1 <= numRows <= 30
解题思路
解题思路
杨辉三角是一个经典的数学结构,每一行的数字都是由上一行相邻两个数字相加得到的。
核心观察:
- 每行的第一个和最后一个元素都是 1
- 中间的元素等于上一行对应位置和前一个位置的元素之和
- 第 i 行有 i+1 个元素(从第0行开始计算)
算法步骤:
- 创建结果数组,第一行固定为 [1]
- 从第二行开始,逐行构建:
- 每行开头和结尾都是 1
- 中间元素通过
triangle[i-1][j-1] + triangle[i-1][j]计算
- 将每一行添加到结果中
优化思路:
- 可以考虑原地构建每一行,减少额外空间使用
- 也可以利用组合数学公式直接计算,但实现复杂度较高
这道题主要考查对二维数组操作和动态规划思想的理解。时间复杂度为 O(numRows²),空间复杂度为 O(1)(不计算返回结果的空间)。
代码实现
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> triangle;
for (int i = 0; i < numRows; i++) {
vector<int> row(i + 1, 1);
for (int j = 1; j < i; j++) {
row[j] = triangle[i - 1][j - 1] + triangle[i - 1][j];
}
triangle.push_back(row);
}
return triangle;
}
};
class Solution:
def generate(self, numRows: int) -> List[List[int]]:
triangle = []
for i in range(numRows):
row = [1] * (i + 1)
for j in range(1, i):
row[j] = triangle[i - 1][j - 1] + triangle[i - 1][j]
triangle.append(row)
return triangle
public class Solution {
public IList<IList<int>> Generate(int numRows) {
IList<IList<int>> triangle = new List<IList<int>>();
for (int i = 0; i < numRows; i++) {
IList<int> row = new List<int>();
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i) {
row.Add(1);
} else {
row.Add(triangle[i - 1][j - 1] + triangle[i - 1][j]);
}
}
triangle.Add(row);
}
return triangle;
}
}
var generate = function(numRows) {
const triangle = [];
for (let i = 0; i < numRows; i++) {
const row = new Array(i + 1).fill(1);
for (let j = 1; j < i; j++) {
row[j] = triangle[i - 1][j - 1] + triangle[i - 1][j];
}
triangle.push(row);
}
return triangle;
};
复杂度分析
| 复杂度类型 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(numRows²) | 需要生成 numRows 行,每行平均有 numRows/2 个元素需要计算 |
| 空间复杂度 | O(1) | 除了返回结果外,只使用了常数级别的额外空间 |