LeetCode 118: Pascal‘s Triangle

LeetCode 118: Pascal's Triangle

    • [1. 📌 Problem Links](#1. 📌 Problem Links)
    • [2. 🧠 Solution Overview](#2. 🧠 Solution Overview)
    • [3. 🟢 Solution 1: Dynamic Programming (Iterative)](#3. 🟢 Solution 1: Dynamic Programming (Iterative))
      • [3.1. Algorithm Idea](#3.1. Algorithm Idea)
      • [3.2. Key Points](#3.2. Key Points)
      • [3.3. Java Implementation](#3.3. Java Implementation)
      • [3.4. Complexity Analysis](#3.4. Complexity Analysis)
    • [4. 🟡 Solution 2: In-Place Update (Space Optimized)](#4. 🟡 Solution 2: In-Place Update (Space Optimized))
      • [4.1. Algorithm Idea](#4.1. Algorithm Idea)
      • [4.2. Key Points](#4.2. Key Points)
      • [4.3. Java Implementation](#4.3. Java Implementation)
      • [4.4. Complexity Analysis](#4.4. Complexity Analysis)
    • [5. 🔵 Solution 3: Recursive Approach](#5. 🔵 Solution 3: Recursive Approach)
      • [5.1. Algorithm Idea](#5.1. Algorithm Idea)
      • [5.2. Key Points](#5.2. Key Points)
      • [5.3. Java Implementation](#5.3. Java Implementation)
      • [5.4. Complexity Analysis](#5.4. Complexity Analysis)
    • [6. 📊 Solution Comparison](#6. 📊 Solution Comparison)
    • [7. 💡 Summary](#7. 💡 Summary)

LeetCode 118: Pascal's Triangle

2. 🧠 Solution Overview

The Pascal's Triangle problem requires generating the first numRows of Pascal's Triangle, where each number is the sum of the two numbers directly above it . Below are the main approaches:

Method Key Idea Time Complexity Space Complexity
Dynamic Programming Build each row based on previous row O(n²) O(n²)
Space-Optimized DP Update rows in place O(n²) O(1) excluding result
Recursive Approach Top-down with memoization O(n²) O(n²)

3. 🟢 Solution 1: Dynamic Programming (Iterative)

3.1. Algorithm Idea

We use iterative dynamic programming where each row is built based on the previous row. The key observation is that each element (except the first and last in each row) equals the sum of the element directly above it and the element to the left of the one directly above it . We systematically build the triangle row by row.

3.2. Key Points

  • Row Construction: Each row starts and ends with 1
  • Inner Elements : triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j]
  • Base Case : First row is always [1]
  • Order Matters: Process rows sequentially from top to bottom

3.3. Java Implementation

java 复制代码
class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> triangle = new ArrayList<>();
        
        if (numRows == 0) return triangle;
        
        // First row is always [1]
        List<Integer> firstRow = new ArrayList<>();
        firstRow.add(1);
        triangle.add(firstRow);
        
        for (int i = 1; i < numRows; i++) {
            List<Integer> prevRow = triangle.get(i - 1);
            List<Integer> currentRow = new ArrayList<>();
            
            // First element is always 1
            currentRow.add(1);
            
            // Calculate inner elements
            for (int j = 1; j < i; j++) {
                currentRow.add(prevRow.get(j - 1) + prevRow.get(j));
            }
            
            // Last element is always 1
            currentRow.add(1);
            
            triangle.add(currentRow);
        }
        
        return triangle;
    }
}

3.4. Complexity Analysis

  • Time Complexity : O(n²) - We process each element in the triangular structure
  • Space Complexity : O(n²) - To store the entire triangle as output

4. 🟡 Solution 2: In-Place Update (Space Optimized)

4.1. Algorithm Idea

This approach optimizes space by reusing arrays and updating values intelligently. It adds 1 at the beginning of each row and then updates the inner values by traversing backwards .

4.2. Key Points

  • Efficient Storage: Use single list and update in reverse order
  • Backward Processing: Update from end to beginning to avoid overwriting values
  • Row Reuse: Modify the same row instead of creating new ones

4.3. Java Implementation

java 复制代码
class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> result = new ArrayList<>();
        if (numRows < 1) return result;
        
        List<Integer> row = new ArrayList<>();
        for (int i = 0; i < numRows; i++) {
            // Add 1 at the beginning
            row.add(0, 1);
            
            // Update inner elements (skip first and last)
            for (int j = 1; j < row.size() - 1; j++) {
                row.set(j, row.get(j) + row.get(j + 1));
            }
            
            result.add(new ArrayList<>(row));
        }
        return result;
    }
}

4.4. Complexity Analysis

  • Time Complexity : O(n²) - Same number of operations as standard DP
  • Space Complexity : O(1) excluding result - Only one temporary row used

5. 🔵 Solution 3: Recursive Approach

5.1. Algorithm Idea

We can solve this recursively by recognizing that each row depends only on the previous row. The recursive approach builds the triangle from the bottom up using the recurrence relation .

5.2. Key Points

  • Base Case : Return [[1]] when numRows = 1
  • Recursive Relation: Build n-1 rows, then construct nth row from (n-1)th row
  • Memoization: Naturally caches previous rows through recursion stack

5.3. Java Implementation

java 复制代码
class Solution {
    public List<List<Integer>> generate(int numRows) {
        // Base case
        if (numRows == 0) return new ArrayList<>();
        if (numRows == 1) {
            List<List<Integer>> triangle = new ArrayList<>();
            triangle.add(Arrays.asList(1));
            return triangle;
        }
        
        // Recursively get previous rows
        List<List<Integer>> prevTriangle = generate(numRows - 1);
        List<Integer> prevRow = prevTriangle.get(prevTriangle.size() - 1);
        List<Integer> currentRow = new ArrayList<>();
        
        currentRow.add(1);
        for (int i = 1; i < prevRow.size(); i++) {
            currentRow.add(prevRow.get(i - 1) + prevRow.get(i));
        }
        currentRow.add(1);
        
        prevTriangle.add(currentRow);
        return prevTriangle;
    }
}

5.4. Complexity Analysis

  • Time Complexity : O(n²) - Same number of operations as iterative approach
  • Space Complexity : O(n²) - For recursion stack and result storage

6. 📊 Solution Comparison

Solution Time Space Pros Cons
Standard DP O(n²) O(n²) Most intuitive, easy to understand Higher memory usage
Space Optimized O(n²) O(1) Memory efficient, clever approach Less intuitive
Recursive O(n²) O(n²) Natural mathematical expression Stack overflow risk for large n

7. 💡 Summary

For Pascal's Triangle problem:

  • Standard DP is recommended for learning and understanding the fundamental pattern
  • Space-optimized approach is best for interviews and memory-constrained environments
  • Recursive solution helps understand the mathematical recurrence but has practical limitations

The key insight is recognizing the combinatorial nature - each element represents binomial coefficients and can be calculated from previous elements using simple addition .

Pascal's Triangle reveals the beautiful simplicity underlying complex patterns - where every new layer builds upon the foundation of what came before, much like the cumulative nature of knowledge itself.

相关推荐
熊猫_豆豆17 分钟前
YOLOP车道检测
人工智能·python·算法
rannn_11117 分钟前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
qq_124987075321 分钟前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
短剑重铸之日27 分钟前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
艾莉丝努力练剑31 分钟前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
若鱼19191 小时前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
觉醒大王1 小时前
强女思维:着急,是贪欲外显的相。
java·论文阅读·笔记·深度学习·学习·自然语言处理·学习方法
偷吃的耗子1 小时前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
努力学编程呀(๑•ี_เ•ี๑)1 小时前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea
码农小卡拉1 小时前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot