leetcode 279:完全平方数

leetcode 279:完全平方数

279. 完全平方数

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,14916 都是完全平方数,而 311 不是。

示例 1:

输入:n = 12
输出:3 
解释:12 = 4 + 4 + 4

示例 2:

输入:n = 13
输出:2
解释:13 = 4 + 9

提示:

  • 1 <= n <= 104

Related Topics

广度优先搜索

数学

动态规划

官方解答:https://leetcode-cn.com/problems/perfect-squares/solution/wan-quan-ping-fang-shu-by-leetcode-solut-t99c/

思路1:动态规划

根据题目要求,设f(i)表示构建i需要多少个完全平方数。

那么这些数肯定是在[1,根号n]。那么我们可以枚举这些数,假设当前数是j,那么选取j之后,还需要若干完全平方数构成i-j^2。那么i-j^2这个数之前已经计算过,可以直接取出。

算法思路:

  1. 计算f(i),选取的平方数范围是[1,根号n],枚举这些数。
  2. 计算构成i-j^2所需的完全平方数的个数,再加上1(j也算1个完全平方数),就是构建i所需要的完全平方数个数(f(i))。
class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n+1];
        for(int i = 1; i <= n;i++){
            //计算构建[i-j^2]所需的最小数
            int min = Integer.MAX_VALUE;
            //构建i的完全平方数范围是[1,根号i]
            for(int j = 1; j*j <= i;j++){
                min = Math.min(min,dp[i-j*j]);
            }
            dp[i] = min + 1;
        }
        return dp[n];
    }
}
解答成功:
			执行耗时:26 ms,击败了66.29% 的Java用户
			内存消耗:40.4 MB,击败了40.14% 的Java用户

思路2:四平方和定理

任意一个数都可以表示为至多四个数的平方和。限制了上界。

  1. 答案为1时,则必有n为完全平方数。
  2. 答案为2时,则必有n = a2+b2,只需要枚举a(1<=a<=根号n),判断n-a2是否为完全平方数。
  3. 当且仅当n不等于4k*(8m+7)时,n最多可被表示3个正整数的平方和。因为我们可以直接计算1,2,4,如果都不符合,那答案肯定是3.
  4. 当n等于4k*(8m+7)时,表示只需要4个正整数平方和。
class Solution {
    public int numSquares(int n) {
       if(isSquares1(n)){
           return 1;
       }
       if(isSquares2(n)){
           return 2;
       }
       if(isSquares4(n)){
           return 4;
       }
       return 3;
    }
    public boolean isSquares1(int x){
        int y = (int)Math.sqrt(x);
        return y*y == x;
    }
    public boolean isSquares2(int x){
        for(int i = 1; i*i <= x;i++){
            int j = x-i*i;
            if(isSquares1(j)){
                return true;
            }
        }
        return false;
    }
    public boolean isSquares4(int x){
        //4^k(8m+7)
        //第一步 除掉4^k次方
        while(x%4==0){
            x /= 4;
        }
        //第二步判断余数是不是7
        return x%8 == 7;
    }
}
解答成功:
			执行耗时:1 ms,击败了97.87% 的Java用户
			内存消耗:38.4 MB,击败了53.23% 的Java用户
			
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值