118. Pascal's Triangle

118. Pascal's Triangle

Photo by Yingchih on Unsplash

Given an integer numRows, return the first numRows of Pascal's triangle. (link)

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

Solution

Brute Force Approach

Calculate the coefficient for each index nCr.

The formula for nCr is given by n! / (r! × (n-r)!). If we attempt to calculate n! first, then r!, and finally (n-r)!, it would result in memory explosion, making it impractical to compute.

Hence, we utilize a shortcut:

nCr = (n x n-1 x ... x n-r+1) / r!

As an example, for 5C3:

5C3 = (5 x 4 x 3) / (1 x 2 x 3)

class Solution {

    public int coefficent(int n, int r){
        int ans = 1;

        for(int i=1; i<=r; i++){
            ans = ans * n / i;
            n-=1;
        }
        return ans;
    }

    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ans = new ArrayList<>();

        for(int n=1; n<=numRows; n++){
            List<Integer> row = new ArrayList<>();
            for(int r=1; r<=n; r++){
                row.add(coefficent(n-1, r-1));
            }
            ans.add(row);
        }
        return ans;
    }
}

Optimal Approach

We can determine the coefficient of the current index by leveraging the coefficient of the preceding index.

Consider the case where n equals 5.

C(4,0) = 1

C(4,1) = 4 -----> (4/1)

C(4,2) = 6------>(4/1 x 3/2)

C(4,3) = 4------>(4/1 x 3/2 x 2/3)

C(4,4) = 1------->(4/1 x 3/2 x 2/3 x 1/4)

class Solution {

    public List<Integer> generateRow(int n){
        List<Integer> row = new ArrayList<>();
        int coeff = 1;
        row.add(coeff);
        for(int r=1; r<n; r++){
            coeff *= n-r;
            coeff/=r;
            row.add(coeff);
        }
        return row;
    }

    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ans = new ArrayList<>();
        for(int n=1; n<=numRows; n++){
            ans.add(generateRow(n));
        }
        return ans;
    }
}

Another Version - Mimicking Pascal's Triangle Addition

With knowledge of the values in the preceding row, we utilize them and subsequently append 1 at the beginning and 1 at the end.

class Solution {

    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ans = new ArrayList<>();
        for(int row=0; row<numRows; row++){
            List<Integer> currRow = new ArrayList<>();
            ans.add(currRow);
            currRow.add(1);
            for(int col=1; col<row; col++){
                int coeff = ans.get(row-1).get(col-1) + ans.get(row-1).get(col);
                currRow.add(coeff);
            }
            if(row!=0){
                currRow.add(1);
            }
        }
        return ans;
    }
}