Problem
Given an integer numRows
, return the first numRows of Pascal’s triangle.
Examples
Example 1:
Input: numRows = 5
Output:[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
This is how the pascal triangle will look:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
Example 2:
Input: numRows = 1
Output:[[1]]
For example, given numRows = 5, the result should be:
Follow up
Can you do this using only O(n)
space? where n is number of rows.
Solution
Method 1 - Recursion
Here is how the recursion work:
- Base case: If numRows is 1, return
[[1]]
. - Recursively generate the triangle for numRows - 1.
- Calculate the current row by summing adjacent elements from the previous row.
Code
Java
class Solution {
public List<List<Integer>> generate(int numRows) {
if (numRows == 0) {
return new ArrayList<>();
}
if (numRows == 1) {
List<List<Integer>> ans = new ArrayList<>();
ans.add(new ArrayList<>(List.of(1)));
return ans;
}
List<List<Integer>> prevRows = generate(numRows - 1);
List<Integer> newRow = new ArrayList<>();
for (int i = 0; i < numRows; i++) {
newRow.add(1);
}
for (int i = 1; i < numRows - 1; i++) {
newRow.set(i, prevRows.get(numRows - 2).get(i - 1) + prevRows.get(numRows - 2).get(i));
}
prevRows.add(newRow);
return prevRows;
}
}
Complexity
- ⏰ Time complexity:
O(n^2)
.generate
is called fornumRows
times, and in that we have loop to fill newRow from old row, and that takesO(n)
time. So, time complexity isO(n^2)
. - 🧺 Space complexity:
O(n)
for the recursive stack.
Method 2 - Generating binomial coeff in each row
We can use Binomial Coefficient. We know that formula is: $$ C(n, k) = \frac{n!}{k! * (n - k)!} $$
We can fill the values in nth row and kth column. For eg.
- row 1 ⇨ n = 0, k = 0 and C(0, 0,) = 1
- row 2 ⇨ n = 1. k is in range
[0, 1]
.C(1, 0) = 1!/0!1! = 1
,C(1, 1) = 1
- and so on.
So, for nth
row, and kth
column we will use C(n - 1, k - 1)
to fill it up.
To sum it up:
- Use the binomial coefficient formula C(n, k) to calculate each element.
- Build the triangle row by row using the formula.
Code
Java
class Solution {
public List < List<Integer>> generate(int numRows) {
List < List<Integer>> ans = new ArrayList<>();
for (int row = 1; row <= numRows; row++) {
List<Integer> currRow = new ArrayList<>();
for (int col = 1; col <= row; col++) {
currRow.add(binomialCoeff(row - 1, col - 1));
}
ans.add(currRow);
}
return ans;
}
private int binomialCoeff(int n, int k) {
int ans = 1;
if (k > n - k) {
k = n - k;
}
for (int i = 0; i < k; ++i) {
ans *= (n - i);
ans /= (i + 1);
}
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n^3)
-O(n^2)
for nested loop in generate, and then O(n) time for generating the binomial coefficient. - 🧺 Space complexity:
O(1)
Method 3 - Reuse the generated binomial coefficient
This is optimization on previous solution. Once, we calculate the value for nth
row, and kth
column, we can use it to generate the values.
If we take a closer at the triangle, we observe that every entry is sum of the two values above it.
Code
Java
class Solution {
public List < List<Integer>> generate(int numRows) {
List <List<Integer>> ans = new ArrayList<>();
// do the first row separately to avoid if condition on prevRow in loop
List<Integer> firstRow = new ArrayList<>();
firstRow.add(1);
ans.add(firstRow);
// note: no row<= numRows, as first row already handled
for (int row = 1; row < numRows; row++) {
List<Integer> prevRow = ans.get(row - 1);
List<Integer> currRow = new ArrayList<>();
currRow.add(1);
// no col <= row here as well, to handle index out of bounds
for (int col = 1; col < row; col++) {
currRow.add(prevRow.get(col - 1) + prevRow.get(col));
}
currRow.add(1);
ans.add(currRow);
}
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n^2)
- 🧺 Space complexity:
O(1)
(as we return the answer, no aux space is used, but O(n) space)