LeetCode 279: Perfect Squares

LeetCode 279: Perfect Squares

    • [1. 📌 Problem Links](#1. 📌 Problem Links)
    • [2. 🧠 Solution Overview](#2. 🧠 Solution Overview)
    • [3. 🟢 Solution 1: Dynamic Programming (Bottom-Up)](#3. 🟢 Solution 1: Dynamic Programming (Bottom-Up))
      • [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: Optimized Dynamic Programming](#4. 🟡 Solution 2: Optimized Dynamic Programming)
      • [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: Mathematical Approach (Lagrange's Four-Square Theorem)](#5. 🔵 Solution 3: Mathematical Approach (Lagrange's Four-Square Theorem))
      • [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)

2. 🧠 Solution Overview

This problem requires finding the minimum number of perfect square numbers that sum to a given integer n. A perfect square is an integer that is the square of an integer (e.g., 1, 4, 9, 16). Below are the main approaches:

Method Key Idea Time Complexity Space Complexity
Dynamic Programming DP array storing min squares for each number O(n√n) O(n)
Space-Optimized DP Similar but more efficient implementation O(n√n) O(n)
Mathematical Approach Using Lagrange's four-square theorem O(√n) O(1)

3. 🟢 Solution 1: Dynamic Programming (Bottom-Up)

3.1. Algorithm Idea

We use a DP array where dp[i] represents the minimum number of perfect squares that sum to i. The key insight is that any number i can be expressed as i = (i - j×j) + j×j for some j, where j×j is a perfect square. Therefore, the solution for i depends on solutions for smaller numbers .

3.2. Key Points

  • State Definition : dp[i] = minimum perfect squares that sum to i
  • State Transition : dp[i] = min(dp[i], dp[i - j×j] + 1) for all j where j×j ≤ i
  • Initialization :
    • dp[0] = 0 (base case: 0 requires 0 squares)
    • Initialize all other dp[i] to a large value (e.g., Integer.MAX_VALUE)
  • Processing Order: Process numbers from 1 to n sequentially

3.3. Java Implementation

java 复制代码
class Solution {
    public int numSquares(int n) {
        // Create DP array with initial large values
        int[] dp = new int[n + 1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0; // Base case
        
        // Precompute all perfect squares up to n
        int maxSquare = (int) Math.sqrt(n);
        int[] squares = new int[maxSquare + 1];
        for (int i = 1; i <= maxSquare; i++) {
            squares[i] = i * i;
        }
        
        // Fill DP table
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= maxSquare; j++) {
                if (squares[j] <= i) {
                    dp[i] = Math.min(dp[i], dp[i - squares[j]] + 1);
                }
            }
        }
        
        return dp[n];
    }
}

3.4. Complexity Analysis

  • Time Complexity : O(n√n) - Outer loop O(n), inner loop O(√n)
  • Space Complexity : O(n) - For the DP array

4. 🟡 Solution 2: Optimized Dynamic Programming

4.1. Algorithm Idea

This is a more optimized version that eliminates the need to precompute all perfect squares. It uses the same DP concept but with more efficient inner loop conditions .

4.2. Key Points

  • Direct Computation : Calculate j×j on the fly instead of precomputing
  • Early Termination : Inner loop runs only while j×j ≤ i
  • Efficient Initialization : Initialize dp[i] = i (worst case: all 1's)

4.3. Java Implementation

java 复制代码
class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n + 1];
        
        for (int i = 1; i <= n; i++) {
            // Worst case: all 1's (i = 1+1+...+1)
            dp[i] = i;
            
            // Try all perfect squares ≤ i
            for (int j = 1; j * j <= i; j++) {
                dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
            }
        }
        
        return dp[n];
    }
}

4.4. Complexity Analysis

  • Time Complexity : O(n√n) - Same as previous DP approach
  • Space Complexity : O(n) - For the DP array

5. 🔵 Solution 3: Mathematical Approach (Lagrange's Four-Square Theorem)

5.1. Algorithm Idea

This approach uses Lagrange's four-square theorem, which states that every natural number can be represented as the sum of four integer squares. The algorithm checks if the number can be represented by 1, 2, or 3 squares before defaulting to 4 .

5.2. Key Points

  • Check for 1 square : If n is a perfect square, return 1
  • Check for 4 squares : If n = 4^k × (8m + 7) for some k, m, return 4
  • Check for 2 squares : Try all i from 1 to √n to see if n - i² is a perfect square
  • Default case: If none of the above, return 3

5.3. Java Implementation

java 复制代码
class Solution {
    public int numSquares(int n) {
        // Check if n is a perfect square
        if (isPerfectSquare(n)) {
            return 1;
        }
        
        // Check four-square condition: n = 4^k × (8m + 7)
        if (isFourSquare(n)) {
            return 4;
        }
        
        // Check if n is sum of two squares
        for (int i = 1; i * i <= n; i++) {
            if (isPerfectSquare(n - i * i)) {
                return 2;
            }
        }
        
        // Default to three squares
        return 3;
    }
    
    private boolean isPerfectSquare(int num) {
        int sqrt = (int) Math.sqrt(num);
        return sqrt * sqrt == num;
    }
    
    private boolean isFourSquare(int n) {
        while (n % 4 == 0) {
            n /= 4;
        }
        return n % 8 == 7;
    }
}

5.4. Complexity Analysis

  • Time Complexity : O(√n) - Much faster than DP approaches
  • Space Complexity : O(1) - Constant space

6. 📊 Solution Comparison

Solution Time Space Pros Cons
Standard DP O(n√n) O(n) Intuitive, guaranteed optimal Slower for large n
Optimized DP O(n√n) O(n) More efficient, simpler code Still polynomial time
Mathematical O(√n) O(1) Optimal time, elegant Harder to understand

7. 💡 Summary

For the Perfect Squares problem:

  • Learning & Understanding : Start with Standard DP to grasp the fundamental pattern
  • Interviews & Practical Use : Optimized DP offers the best balance of understandability and efficiency
  • Production & Performance : Mathematical Approach provides optimal O(√n) performance

The key insight for DP is recognizing the optimal substructure - the solution for each number can be built from solutions for smaller numbers by considering all possible perfect squares .

The search for perfect squares reveals the beautiful interplay between mathematical theory and computational practice - where deep number theory theorems can provide elegant solutions to seemingly complex optimization problems.

相关推荐
yeflx8 分钟前
速腾Airy雷达使用记录
java·服务器·网络
乐之者v29 分钟前
AI编程 -- Agents.md 的简单示例
java·ai编程
wabs66632 分钟前
关于图论【广度优先搜索的理论基础】
算法·图论·宽度优先
孤魂23336 分钟前
逻辑回归算法
算法·机器学习·逻辑回归
weixin_3776348439 分钟前
【多模型预测】 如何合理融合多个预测分值
算法·机器学习·概率论·预测·agent预测
无风听海1 小时前
Claude Agent Skills 的四种设计模式;从渐进式披露到最小权限
java·算法·设计模式
37.2℃9951 小时前
专业的Claude Design解决方案
前端·算法
め.1 小时前
定点数运算库
算法·unity
yuannl101 小时前
图的深度优先遍历DFS
数据结构
dyxal1 小时前
最长公共子序列(LCS)
python·算法