118. Pascal’s Triangle¶
Edited by Charles
Easy · Python · Dynamic Programming
Problem
Read the original problem on LeetCode.
The official page contains the problem statement, examples, and constraints.
Explanation, examples & other approaches
Core idea
Given an integer numRows, return the first numRows rows of Pascal's Triangle.
Original study notes follow, including intermediate snippets and earlier attempts.
Problem¶
Given an integer numRows, return the first numRows rows of Pascal's Triangle.
For example:
we should return:
Pascal's Triangle looks like:
The key observation is:
Every row of Pascal's Triangle can be generated from the previous row.
We use:
to represent the entire i-th row of Pascal's Triangle.
Since Python uses 0-based indexing:
The first two rows are:
Therefore:
Since accessing:
requires at least two rows, we separately handle:
So the initialization is:
Every row of Pascal's Triangle has the following structure:
The first and last elements are always:
For every middle element:
we add the two adjacent elements from the previous row:
Therefore:
Consider:
For example:
For position j in the current row, its two parents in the previous row are:
and:
Therefore:
We only need to calculate the middle elements.
The first element is already:
and the last element is also:
Therefore, for the previous row:
we calculate:
For example:
Its length is:
Therefore:
gives:
and we calculate:
j = 1:
dp[i-1][0] + dp[i-1][1]
= 1 + 3
= 4
j = 2:
dp[i-1][1] + dp[i-1][2]
= 3 + 3
= 6
j = 3:
dp[i-1][2] + dp[i-1][3]
= 3 + 1
= 4
So the middle part becomes:
Then we add 1 to both sides:
giving:
This allows us to construct one row directly using:
This line directly represents the mathematical structure of Pascal's Triangle:
Consider:
Initially:
Generate Row 3¶
Previous row:
Middle elements:
Therefore:
gives:
Now:
Generate Row 4¶
Previous row:
Middle elements:
Therefore:
gives:
Generate Row 5¶
Previous row:
Middle elements:
Therefore:
gives:
Final result:
Since we already initialize:
we could technically start from:
instead of:
because row 1 is already known.
So a slightly cleaner version of the same approach is:
This avoids calculating:
again.
Time Complexity¶
We generate:
elements.
Therefore:
This is already optimal because the output itself contains:
numbers.
Space Complexity¶
The complete Pascal's Triangle contains:
elements.
Therefore:
space is required for the returned result.
Define:
Every row has the structure:
For each middle position:
So the entire row can be constructed elegantly as:
The most useful way to remember this problem is:
Time Complexity:
Space Complexity:
Study record
| Field | Value |
|---|---|
| Attempts | 1 |
| Mastery | ❚ |
| The Latest Attempt | September 18, 2026 |
Python solution¶
class Solution:
def generate(self, numRows: int) -> list[list[int]]:
if numRows == 1:
return [[1]]
dp = [[] for _ in range(numRows)]
dp[0] = [1]
dp[1] = [1, 1]
for i in range(2, numRows):
dp[i] = (
[1]
+ [
dp[i - 1][j] + dp[i - 1][j - 1]
for j in range(1, len(dp[i - 1]))
]
+ [1]
)
return dp