Medium草稿★★★★★O(n * sqrt(n)) 時間 · O(n) 空間
Dynamic ProgrammingMathBFS
Patterns🌊 廣度優先 BFS📈 線性 DP・Kadane🧮 數學・組合
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

279Perfect Squares1-D DPMedium1-D DP

給定正整數 n,找出最少需要多少個完全平方數(1, 4, 9, 16, …)的和等於 n

Example:

Input: n = 12 Output: 3

Intuition

TIP

完全背包變體:物品是所有完全平方數,求湊成 n 的最少物品數。

Approaches

1. Top-Down Memoization — O(n * sqrt(n)) / O(n)
  • Idea: 遞迴嘗試減去每個完全平方數,記憶化結果
  • Time: O(n * sqrt(n))
  • Space: O(n)
class Solution {
    fun numSquares(n: Int): Int {
        val memo = IntArray(n + 1) { -1 }
        fun dp(rem: Int): Int {
            if (rem == 0) return 0
            if (memo[rem] != -1) return memo[rem]
            var best = rem // 最差情況全用 1
            var j = 1
            while (j * j <= rem) {
                best = minOf(best, dp(rem - j * j) + 1)
                j++
            }
            memo[rem] = best
            return best
        }
        return dp(n)
    }
}
⭐ 2. Bottom-Up DP — O(n * sqrt(n)) / O(n)
  • Idea: 從 1 到 n 逐步計算每個值的最少完全平方數個數
  • Time: O(n * sqrt(n))
  • Space: O(n)
class Solution {
    fun numSquares(n: Int): Int {
        val dp = IntArray(n + 1) { it } // 最差全用 1
        for (i in 1..n) {
            var j = 1
            while (j * j <= i) {
                dp[i] = minOf(dp[i], dp[i - j * j] + 1)
                j++
            }
        }
        return dp[n]
    }
}

🔑 Takeaways