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.

相关推荐
源代码•宸23 分钟前
分布式缓存-GO(分布式算法之一致性哈希、缓存对外服务化)
开发语言·经验分享·分布式·后端·算法·缓存·golang
It's now34 分钟前
Spring AI 基础开发流程
java·人工智能·后端·spring
cxh_陈34 分钟前
线程的状态,以及和锁有什么关系
java·线程·线程的状态·线程和锁
计算机毕设VX:Fegn089537 分钟前
计算机毕业设计|基于springboot + vue图书商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
R.lin1 小时前
Java 8日期时间API完全指南
java·开发语言·python
毕设源码-赖学姐1 小时前
【开题答辩全过程】以 高校教学质量监控平台为例,包含答辩的问题和答案
java·eclipse
yongui478341 小时前
MATLAB的指纹识别系统实现
算法
高山上有一只小老虎1 小时前
翻之矩阵中的行
java·算法
jghhh011 小时前
RINEX文件进行卫星导航解算
算法
火钳游侠1 小时前
java单行注释,多行注释,文档注释
java·开发语言