关注
文末的名片达文汐
,回复关键词“力扣源码”,即可获取完整源码!!详见:源码和核心代码的区别
题目详情
给定一个非负整数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
解题思路
题目要求生成杨辉三角的前 numRows 行。杨辉三角的特点是:
- 每行的第一个和最后一个元素始终为 1。
- 中间元素的值等于上一行中同位置和前一个位置元素之和。
优化思路:
- 空间优化:直接利用上一行计算当前行,避免重复计算。
- 时间优化:按行顺序生成,每行元素通过动态规划方式计算,时间复杂度 O(numRows²),这是最优解。
- 边界处理:单独处理第 0 行(即第一行),从第 1 行开始循环生成后续行。
算法步骤:
- 初始化结果列表
result
。 - 添加第一行
[1]
。 - 循环生成第 1 行至第
numRows-1
行:- 每行首尾元素为 1。
- 中间元素
j
的值 = 上一行[j-1]
+ 上一行[j]
。
- 返回结果列表。
代码实现(Java版)
class Solution {
public List<List<Integer>> generate(int numRows) {
// 初始化结果列表
List<List<Integer>> result = new ArrayList<>();
if (numRows <= 0) {
return result;
}
// 添加第一行
result.add(new ArrayList<>());
result.get(0).add(1);
// 从第1行开始生成(行索引i从1到numRows-1)
for (int i = 1; i < numRows; i++) {
List<Integer> row = new ArrayList<>(); // 当前行
List<Integer> prevRow = result.get(i - 1); // 上一行
row.add(1); // 首元素为1
// 计算中间元素:j从1到i-1
for (int j = 1; j < i; j++) {
int num = prevRow.get(j - 1) + prevRow.get(j);
row.add(num);
}
row.add(1); // 尾元素为1
result.add(row); // 将当前行加入结果
}
return result;
}
}
代码说明
-
初始化与边界处理:
- 若
numRows <= 0
,直接返回空列表。 - 第一行固定为
[1]
。
- 若
-
动态生成后续行:
- 行循环:从第 1 行(索引
i=1
)开始生成,直到第numRows-1
行。 - 首尾元素:每行首尾固定添加
1
。 - 中间元素:通过上一行的
[j-1]
和[j]
位置元素求和得到当前行位置j
的值。
- 行循环:从第 1 行(索引
-
时间复杂度:O(numRows²),因需生成 numRows 行,每行最多 numRows 个元素。
-
空间复杂度:O(numRows²),存储结果所需空间。