Given an integer numRows, build the first numRows rows of Pascal's triangle and return them.
Pascal's triangle starts with a single 1 at the top. Every entry below is the sum of the two entries directly above it; where there is only one entry above (the left and right edges), the value is always 1.
Return the triangle as a list of rows, where row i (0-indexed) contains i + 1 numbers.
1 straight down from the apex.numRows <= 30 the largest value is C(29, 14) = 67863915, well within a 32-bit int. The multiplicative method multiplies before dividing, so intermediate products stay small too.O(k) space" variant. Keep one array and update it in place from right to left, or use the C(k, j) scaling trick to emit one row without building the others.O(n²), so that cost is unavoidable, but you can stream rows one at a time and, if only specific entries are needed, compute them modulo a prime using precomputed factorials.Input: numRows = 5 Output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] Each interior number is the sum of the two above it: 2 = 1+1, 3 = 1+2, 6 = 3+3.
Input: numRows = 1 Output: [[1]] Just the apex of the triangle.
- 1 <= numRows <= 30
Pascal's Triangle is a lesson in recognizing when you're already at the optimal complexity. The answer is O(n²) numbers, so no algorithm can be faster than O(n²) — the only thing left to optimize is how much you carry between rows. The classic build sums the two entries above each cell; the slicker build treats each row as binomial coefficients.
1s on the edges.k of row i is C(i, k) — the same numbers that expand (a+b)^i. This lets you skip storing the previous row.O(n²) entries, O(n²) work is optimal — you can't emit fewer numbers than the answer contains.Given numRows, return the first numRows rows of Pascal's triangle. Row i (0-indexed) has i+1 entries; the first and last are always 1.
Worked example — numRows = 5
row 0: 1 row 1: 1 1 row 2: 1 2 1 2 = 1+1 row 3: 1 3 3 1 3 = 1+2 row 4: 1 4 6 4 1 6 = 3+3
“Are rows 0-indexed, and how many entries does row i have?”
0-indexed; row i has i+1 entries. Confirms the shape of the output.
“Can numRows be 1?”
Yes — just the apex [[1]].
“Could the values overflow?”
For numRows <= 30 the largest entry is C(29,14) ≈ 6.8×10⁷, safe in 32-bit. The multiplicative build multiplies before dividing to keep intermediates small.
“Return the full triangle as a list of rows?”
Yes — a jagged list where each row is its own list.
“How big can numRows be?”
Up to 30. The output has O(numRows²) entries, so O(numRows²) time is unavoidable and perfectly fine here.
A couple of quick questions.
Rows are 0-indexed, and row i has i+1 entries?
I return the whole triangle as a list of rows?
Since the output itself is O(n²), I'll build it row by row from the one above.
Interior entry row[j] = prev[j-1] + prev[j], and the edges (j = 0 or j = i) are always 1. That single rule builds every row from the one above — the most direct way to generate the triangle.
There are 1 + 2 + ... + numRows entries to produce. You cannot output them in fewer steps than there are numbers, so O(numRows²) is a lower bound — the goal isn't a faster asymptotic, just less carried state.
Entry k of row i is C(i, k). Stepping across a row, C(i, k) = C(i, k-1) × (i - k + 1) / k. So you can emit a whole row by scaling a single running number left to right — no need to remember the previous row at all.
| Sum from above | Binomial scan | |
|---|---|---|
| Idea | row[j] = prev[j-1] + prev[j] | Scale C(i,k-1) → C(i,k) across the row |
| Time | O(n²) | O(n²) |
| Needs previous row |
The full code for both is in the Approaches selector below.
Key takeaway
Pascal's triangle is output-bound at O(n²), so the win is in carried state, not speed. Build each row from the previous by summing adjacent pairs — or recognise each row as binomial coefficients C(i,k) and scale one running value across it (multiplying before dividing) to avoid storing the prior row entirely.