題目描述:給定正整數 n,找出最少需要多少個完全平方數(例如 1、4、9、16…)相加才能等於 n。
解題思路:
動態規劃(DP)解法:定義 dp[i] 為組成數字 i 所需的最少完全平方數個數。初始化 dp[0] = 0(空的組合),其餘設為無窮大。
對於每個 i 從 1 到 n,枚舉所有完全平方數 j*j ≤ i:
dp[i] = min(dp[i], dp[i - j*j] + 1)
此轉移式的含義:若選用完全平方數 j²,則問題縮減為「用最少個數組成 i - j²」,加上這一個 j² 本身。
BFS 解法(另一視角):把數字 0 到 n 視為圖的節點,若 a - b 是完全平方數則連邊。從 0 出發做 BFS,第一次到達 n 的層數就是答案。每一層代表多用了一個完全平方數,BFS 保證第一次到達即為最短路徑(最少個數)。
時間複雜度:O(n√n) — 外層迴圈 O(n),內層枚舉完全平方數至 √i,最壞約 O(√n),整體為 O(n√n)。
空間複雜度:O(n) — dp 陣列大小為 n+1,與輸入規模線性相關。
1. Initialize dp array of size n+1, all set to INT_MAX; dp[0] = 0
2. For i from 1 to n:
a. For j from 1 while j*j <= i:
dp[i] = min(dp[i], dp[i - j*j] + 1)
j++
3. Return dp[n]方法一:BFS(廣度優先搜尋)
以 0 為起點,每次從當前數字加上一個完全平方數到達下一個數字,用 BFS 求到達 n 的最短步數。使用 visited 集合避免重複訪問。時間複雜度 O(n√n),空間複雜度 O(n)。BFS 在概念上等同於 DP,但實作上需要佇列和 visited 集合,常數較大。
方法二:數學定理(Legendre's Three-Square Theorem)
根據拉格朗日四平方和定理,任意正整數都能表示為最多 4 個完全平方數之和。可透過以下規則 O(√n) 時間得出答案:
n = 4^a * (8b + 7) 形式 → 答案為 4