Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

118. Pascal's Triangle - Leetcode Solution

Code Implementation

class Solution:
    def generate(self, numRows: int) -> list[list[int]]:
        triangle = []
        for row_num in range(numRows):
            row = [1] * (row_num + 1)
            for j in range(1, row_num):
                row[j] = triangle[row_num - 1][j - 1] + triangle[row_num - 1][j]
            triangle.append(row)
        return triangle
      
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 {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> triangle = new ArrayList<>();
        for (int i = 0; i < numRows; i++) {
            List<Integer> row = new ArrayList<>();
            for (int j = 0; j <= i; j++) {
                if (j == 0 || j == i) {
                    row.add(1);
                } else {
                    row.add(triangle.get(i-1).get(j-1) + triangle.get(i-1).get(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;
};
      

Problem Description

Given an integer numRows, generate the first numRows of Pascal's Triangle. Pascal's Triangle is a triangular array where each number is the sum of the two numbers directly above it. The first and last element of each row is always 1.

  • Each row i contains i + 1 elements.
  • The triangle starts with a single 1 at the top.
  • Return a list of lists (or equivalent structure) representing the triangle up to numRows.

Thought Process

To solve this problem, we need to understand how Pascal's Triangle is constructed. The first row is just [1]. For each subsequent row, the first and last elements are always 1, and each inner element is the sum of the two elements directly above it from the previous row.

The brute-force way would be to compute each value independently using combinations (n choose k), but that's inefficient and ignores the recursive nature of the triangle. Instead, we can build each row based on the previous row, which allows us to construct the triangle efficiently and intuitively.

Solution Approach

  • Step 1: Initialize an empty list (or array) to hold all rows of the triangle.
  • Step 2: Loop from 0 to numRows - 1 (for each row).
  • Step 3: For each row, create a new list with rowIndex + 1 elements, all initialized to 1.
  • Step 4: For positions between the first and last, set row[j] = triangle[rowIndex - 1][j - 1] + triangle[rowIndex - 1][j]. This adds the two numbers directly above.
  • Step 5: Append the row to the triangle.
  • Step 6: After the loop, return the triangle.

This approach is efficient because we only use previously computed values and avoid recalculating combinations or factorials.

Example Walkthrough

Let's walk through the process with numRows = 5:

  1. Start with an empty triangle: []
  2. Row 0: [1] (first row is always [1])
  3. Row 1: [1, 1] (first and last are 1)
  4. Row 2: Start with [1, 1, 1]. Set row[1] = triangle[1][0] + triangle[1][1] = 1 + 1 = 2. So, row becomes [1, 2, 1]
  5. Row 3: Start with [1, 1, 1, 1]. Set row[1] = 1 + 2 = 3, row[2] = 2 + 1 = 3. Row: [1, 3, 3, 1]
  6. Row 4: Start with [1, 1, 1, 1, 1]. Set row[1] = 1 + 3 = 4, row[2] = 3 + 3 = 6, row[3] = 3 + 1 = 4. Row: [1, 4, 6, 4, 1]

The final triangle is:

  • [1]
  • [1, 1]
  • [1, 2, 1]
  • [1, 3, 3, 1]
  • [1, 4, 6, 4, 1]

Time and Space Complexity

  • Brute-force approach:
    • If we compute each entry using combinations (factorials), each computation is O(n), and there are O(n^2) entries, so total O(n^3).
  • Optimized approach (used here):
    • We fill each entry once, and there are a total of 1 + 2 + ... + n = n(n+1)/2 entries, so time complexity is O(n^2).
    • Space complexity is also O(n^2) because we store all rows.

Summary

By recognizing the recursive structure of Pascal's Triangle, we can efficiently build each row using values from the previous row. This approach avoids unnecessary computations and leverages the properties of the triangle. The solution is elegant because it directly mirrors the mathematical definition and is easy to implement in any programming language.