【LeetCode】279. Perfect Squares
阿新 • • 發佈:2018-12-21
Description:
Given a positive integer n, find the least number of perfect square numbers (for example,
1, 4, 9, 16, ...
) which sum to n.
Example 1:
Input: n = 12 Output: 3 Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13 Output: 2 Explanation: 13 = 4 + 9.
題目分析:
這是一道動態規劃題目,要解決動態規劃題目需要掌握三個資訊:
- 最優子結構(最難的是發現最優子結構)
- 邊界條件
- 根據最優子結構寫出狀態轉移方程
重疊子問題:
我們用陣列dp[i]表示第i個數字的完美平方數。我們來尋找重疊子問題:
我們要找到13的完美平方數,就把13拆成兩個數的和,在分別找到這兩個數的完美平方數,這就是這道題的重疊子問題。但是有一點我們不能忽略,如果這個13剛好是一個數的平方,那麼它的完美平方數就是1。
最優子結構分析:
13的完美平方數 = Min( dp[i]+dp[13-i] , dp[13]) ; i = 1到 13/2。
狀態轉移方程:
根據上面分析出來的最優子結構,我們可以寫出來這道題的狀態轉移方程:
i 的完全平方數是從和為 i 的兩個完全平方數 dp[j] 和 dp[i-j]之和 與 dp[i ]中取最小。
【類似題目】
已經AC的程式碼:
import java.util.Arrays; public class Numsquares_279 { public static void main(String[] args) { // TODO Auto-generated method stub for(int i=1; i<=20; i++) System.out.println(numSquares(i)); } public static int numSquares(int n) { int[] dp = new int[n+1]; Arrays.fill(dp, Integer.MAX_VALUE); dp[1] = 1; for(int i=1; i<=n; i++) { int sqr = (int)Math.sqrt(i); //如果i本身是個平方數,就將dynamicProgramming[i]置為1 if(sqr * sqr == i) dp[i] = 1; else { //從1開始遍歷所有和為i的最優解dp[i],使得dp[i]取值最小 for(int j=1; j<=i/2; j++) dp[i] = Math.min(dp[j]+dp[i-j], dp[i]); } } return dp[n]; } }
Reference: