力扣Leetcode:279. 完全平方数

目录

解法一:动态规划

解法二:四平方和定理


解法一:动态规划

对于一个数n来说,要求完全平方数的数量,它的完全平方数必然在区间  (根号下n需要向下取整)。那么对于在这个区间内的数 m,必然满足

在这种情况下,n的完全平方数的数量(用 f(n) 表示)为:

要求最少的数量,那就要比较这个区间里的所有元素,找出一个最少的来,所以,令表示正整数n的最少数量的完全平方和。则

其中m=sqrt(n)向下取整。

c++代码:

class Solution {
public:
    int numSquares(int n) {
        int f[n+1];
        memset(f,0, sizeof(f));
        f[0] = 0;
        f[1] = 1;
        for(int i = 2; i <= n; i++){
            int m = sqrt(i);
            int min = 9999;
            for(int j = 1; j <= m; j++){
                int tmp = f[i-j*j] + 1;
                if(min > tmp){
                    min = tmp;
                }
            }
            f[i] = min;
        }
        return f[n];
    }
};

 

解法二:四平方和定理

定理内容:每个正整数均可表示成不超过四个整数的平方之和。

重要的推论:一个正整数 n, 如果只能被表示成四个整数的平方和,必定满足:

定理的证明:https://zhuanlan.zhihu.com/p/104030654

定理的内容以及推论:https://blog.csdn.net/l_mark/article/details/89044137

解决方案:

要求最少数量,根据分析只存在四种情况,最少数量m = 1,2,3,4。

  1. 判断m=1的情况,也就是n=a*a。
  2. 判断m=4的情况,也就是判断式子是否成立。
  3. 判断m=2的情况,也就是n=a*a+b*b。遍历区间1 <= i <= sqrt(n),判断n-i*i是否是完全平方数,如果是,则m=2。
  4. 其余情况,m=3。
class Solution {
public:
    int numSquares(int n) {
        int t = sqrt(n);
        if(t*t == n) return 1; //判断m=1
        t = n;
        while(t % 4 == 0){
            t = t / 4;
        }
        t = t % 8;
        if(t == 7) return 4; //判断m=4
        int m = sqrt(n);
        for(int i = 1; i <= m; i++){
            int a = i * i; 
            int b = sqrt(n-a);
            if(b*b == (n-a)) return 2; //判断m=3
        }
        return 3; //其余情况m=3
    }
};

下面是执行记录,第一个是解法二的,第二个是解法一的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值