1. 程式人生 > >279. 完全平方數

279. 完全平方數

給定正整數 n,找到若干個完全平方數(比如 1, 4, 9, 16, ...)使得它們的和等於 n。你需要讓組成和的完全平方數的個數最少。

示例 1:

輸入: n = 12
輸出: 3 
解釋: 12 = 4 + 4 + 4.

示例 2:

輸入: n = 13
輸出: 2
解釋: 13 = 4 + 9.

=====================================================================

解題思路,動態規劃..

dp[n]用來記錄n最小可以有幾個平方陣列成

狀態轉移方程 :  dp[n] = min(dp[n-j*j]+1,dp[n])  

遍歷從1到j(j*j<n),可以得到dp[n]中最小的解,更新dp[n]的值

時間複雜度O(n^2)

貼一下程式碼

class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n+1];
        dp[0] = 0;
        for(int i=0;i<n+1;i++)
            dp[i]=i;
        for (int i = 1; i <= n; ++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個情況

n%8==7滿足這樣條件的數,只能由4個組成

如果能被開方,返回1,

遍歷 1到 x (x^2<n)

如果n-x可以被開方,就返回2

剩餘的返回3

這樣的話是O(logn),S(1)

貼一下程式碼,不是我寫的..

class Solution {
    public int numSquares(int n) {
      while (n % 4 == 0)
			n /= 4;
		if (n % 8 == 7)
			return 4;
		for (int a = 0; a * a <= n; ++a) {
			int b = (int) Math.sqrt(n - a * a);
			if (a * a + b * b == n) {
				if (a == 0 || b == 0) {
					return 1;
				}
				return 2;
				}
		}
		return 3;
    }
}