leetcode hot 100-279. 完全平方數
阿新 • • 發佈:2020-10-12
279. 完全平方數
題目描述
給定正整數n,找到若干個完全平方數(比如1, 4, 9, 16, ...)使得它們的和等於 n。你需要讓組成和的完全平方數的個數最少。
示例1:
輸入: n = 12 輸出: 3 解釋: 12 = 4 + 4 + 4.
示例 2:
輸入: n = 13 輸出: 2 解釋: 13 = 4 + 9.
思路一:暴力 dfs (時間超時)
先給n開平方,確定上界,假定根號n等於k 遞迴,從1-k中選出多個值,每個值可選可不選,而且還能重複選,記錄選中的次數 當前和如果剛好等於n,則更新cnt1 class Solution { 2 publicint numSquares(int n) { 3 if(n <= 0){ 4 return 0; 5 } 6 7 // 先給n開平方,確定上界,假定 根號n等於k 8 int sqrt = (int)Math.sqrt(n); 9 traceBack(n, 0, sqrt, 0); 10 return cnt; 11 } 12 13 public int cnt = 1 << 30; 14 15 // 遞迴,從1-k中選出多個值,每個值可選可不選,而且還能重複選,記錄選中的次數16 public void traceBack(int n, int nowSum, int index, int count){ 17 // 越界,或者如果大於n, 直接返回 18 if(index <= 0 || n < nowSum){ 19 return; 20 } 21 // 邊界如果剛好等於n, 則更新cnt 22 if(n == nowSum){ 23 cnt = Math.min(cnt, count); 24 } 25 26// 對於每個數可選也不可選 27 // 選 28 if(nowSum + index * index <= n){ 29 traceBack(n, nowSum + index * index, index, count + 1); 30 } 31 32 // 不選 33 traceBack(n, nowSum, index-1, count); 34 } 35 }
通過了287個測試用例,然後就超時了
複雜度分析:
時間複雜度:對小於√n 的所有數都進行列舉,而且每個數還不止列舉一遍,所以這個複雜度就不太好算了,我覺得是 2n√n
空間複雜度:遞迴棧的深度,我覺得是√n
思路二:動態規劃
dp[i]表示組成i的最少完全平方的個數 i和(i-j*j)的最終結果就相差一個完全平方數j*j,所以dp[i]和dp[i-j*j]就相差1 dp[i]=Math.min(dp[i],dp[i-j*j]+1); dp[0] = 0; 邊界值dp[i]=i,因為組成i的最少完全平方的個數最大為i,即全是由1組成的1 class Solution { 2 public int numSquares(int n) { 3 if(n <= 0){ 4 return 0; 5 } 6 7 int[] dp = new int[n+1]; 8 dp[0] = 0; 9 for(int i = 1; i <= n; i++){ 10 dp[i] = i; 11 for(int j = 0; i - j*j >= 0; j++){ 12 dp[i] = Math.min(dp[i], dp[i - j*j] + 1); 13 } 14 } 15 return dp[n]; 16 } 17 }leetcode 執行用時:42 ms > 64.61%, 記憶體消耗:37.5 MB > 94.62%