leetcode 279. 完美平方数

题目

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.

分析

  • 先说我自己写的哦,我写的比较暴力,就是遍历了n的所有加数,取得他们的最小平方数个数,在这过程中用一个一维数组保存了一下中间量,免得重复计算,就这样,我虽然说是通过了,但是是1100+ms,也是很长时间了,再看前面的人,大都是2ms再不行是50ms左右。
    是我时间复杂度太高了,然后看了下他们前面的代码,先看的是2ms左右的代码。

原来有一个定理,四平方和定理。

四平方和定理说明每个正整数均可表示为4个整数的平方和。

  • 它还有一个公式,正好我们这道题可以用得上:
    n = 4^k * ( 8*m +7)
    那这样我们就可以根据这个公式来判断出n这个整数它的返回值是不是4,
    当然n也有可能=3/2/1,判断完上面,我们继续筛选,n=2或1的情况也还是比较好判断的,判断n是不是等于两个平方数相加。筛选完2和1的情况,也不用判断就是3啦。

  • 这个是用的公式,也并不能帮我改进我自己写的复杂度高的算法。
    那下面这个就算是我的优化了:
    我直接贴代码吧,其实我看得有些稀里糊涂

// 这是我寄几的
class Solution {
    public int numSquares(int n) {
        int[] minFactor = new int[n+1];
        for (int i = 0; i < n+1; i++) {
            minFactor[i] = Integer.MAX_VALUE;
        }
        for (int i = 1; i*i < n+1; i++) {
            minFactor[i*i] = 1;
        }
        findMin(minFactor,n);
        // print(minFactor);
        return minFactor[n];
    }
    
    public static void findMin(int[] minFactor, int n){
        for (int i = 1; i <= n/2; i++) {
            int addnum = n - i;
            if (minFactor[i] == Integer.MAX_VALUE){
                findMin(minFactor,i);
            }
            if (minFactor[addnum] == Integer.MAX_VALUE)
                findMin(minFactor,addnum);
            minFactor[n] = Math.min(minFactor[n],minFactor[i]+minFactor[addnum]);
        }
    }
}


//这是优化的
class Solution {
    public int numSquares(int n) {
		int f[] = new int[n + 1];
		for (int i = 1; i <= n; i++)
			f[i] = i;
		for (int i = 2; i <= n; i++)
			for (int j = 1; j * j <= i; j++)
				f[i] = Math.min(f[i], f[i - j * j] + 1);
		return f[n];
	}
}

//这是用四平方定理的
class Solution {
    public int numSquares(int n) {
        while (n % 4 == 0) {
            n /= 4;
        }
        if (n % 8 == 7) {
            return 4;
        }
        for (int i = 0; i * i <= n; i++) {
            int j = (int) Math.sqrt(n - i * i);
            if (i * i + j * j == n) {
                return i * j == 0 ? 1 : 2;
            }
        }
        return 3;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38595487/article/details/83350798
今日推荐