Advertisement

Pascal's Triangle - LeetCode 118 Solution

Pascal's Triangle - Complete Solution Guide

Pascal's Triangle is LeetCode problem 118, a Easy level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

Given an integer numRows , return the first numRows of Pascal's triangle . In Pascal's triangle , each number is the sum of the two numbers directly above it as shown: Example 1: Input: numRows = 5 Output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] Example 2: Input: numRows = 1 Output: [[1]] Constraints: 1 <= numRows <= 30

Detailed Explanation

Pascal's Triangle presents a visually elegant pattern that's surprisingly straightforward to generate algorithmically. At its core, the problem asks us to construct the first `numRows` of this famous mathematical triangle. The defining characteristic is simple: every number inside the triangle (i.e., not at the very edge) is the sum of the two numbers directly above it. The edges of each row are always `1`. For instance, if `numRows = 5`, the third row `[1,2,1]` is derived from the second row `[1,1]` where the '2' comes from `1 + 1`. The fourth row `[1,3,3,1]` similarly uses the third row `[1,2,1]` to calculate its inner '3's (first '3' is `1+2`, second '3' is `2+1`).

Solution Approach

The provided solution embraces the inherent dynamic programming nature of Pascal's Triangle. It constructs the triangle row by row, building upon the results of the preceding row. We start by initializing an empty list, `triangle`, which will eventually hold all our rows. For each row index `i` from `0` up to `numRows - 1`: A new `row` is initialized. Crucially, it's created as a list of `i + 1` ones (e.g., `[1] * (i + 1)`). This cleverly handles the fixed '1's at the beginning and end of every row for all `i`. For rows beyond the second one (i.e., `i > 1`), we then iterate with `j` from `1` to `i - 1`. This range specifically targets the elements *between* the leading and trailing '1's that we just pre-filled. Inside this loop, the core dynamic programming step occurs: `row[j] = triangle[i - 1][j - 1] + triangle[i - 1][j]`. This directly translates the rule 'each number is the sum of the two numbers directly above it', using the already computed `(i - 1)`-th row. Once the current `row` is fully constructed, it's appended to the `triangle` list. This iterative process ensures that by the time we need to calculate `row i`, `row i-1` (which it depends on) is already present and fully correct in `triangle`.

Step-by-Step Algorithm

  1. Step 1: Initialize an empty list (or 2D array) to store the Pascal's Triangle.
  2. Step 2: Iterate from 0 to `numRows - 1` (representing each row).
  3. Step 3: For each row, create a new row list (or array) of size `i + 1` and initialize all elements to 1.
  4. Step 4: If the row index `i` is greater than 1, iterate from 1 to `i - 1` to calculate the intermediate elements of the row using the formula: `row[j] = triangle[i - 1][j - 1] + triangle[i - 1][j]` (sum of elements from the previous row).
  5. Step 5: Append the newly created row to the Pascal's Triangle list.
  6. Step 6: After the loop finishes, return the Pascal's Triangle list.

Key Insights

  • **Direct Translation of the Summation Rule:** The core mathematical property `P(row, col) = P(row-1, col-1) + P(row-1, col)` is directly implemented. Each element at an inner position `j` in the current row `i` is precisely the sum of elements at `j-1` and `j` from the *previous* row `i-1`.
  • **Leveraging Prior Computations (Dynamic Programming):** The solution explicitly uses the previously generated row (`triangle[i - 1]`) to construct the current one. This avoids redundant calculations, as each row (a subproblem) is computed once and stored, then directly accessed for subsequent rows.
  • **Efficient Boundary Handling:** Instead of special-casing for the leading and trailing '1's in each row with separate conditional logic, the solution initializes `row = [1] * (i + 1)`. This simple step efficiently sets up the correct length and automatically populates the boundary '1's, making the subsequent inner loop solely responsible for computing the sums of the interior elements.

Complexity Analysis

Time Complexity: O(n^2)

Space Complexity: O(n^2)

Topics

This problem involves: Array, Dynamic Programming.

Companies

Asked at: Accenture, Cisco, Deloitte, Goldman Sachs, Google, HSBC, J.P. Morgan, Mitsogo, Oracle, Uber, Virtusa, Wix, X, Yahoo, tcs.