平方数之和

题目

给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。

示例 1:

输入:c = 5
输出:true
解释:1 * 1 + 2 * 2 = 5

示例 2:

输入:c = 3
输出:false

示例 3:

输入:c = 4
输出:true

示例 4:

输入:c = 2
输出:true

示例 5:

输入:c = 1
输出:true

提示:

0 <= c <= 231 - 1

题解

方法一:sqrt 函数

class Solution {
    public boolean judgeSquareSum(int c) {
    	// long型避免int类型溢出(c有范围)
        for(long a=0;a*a<=c;a++){
            double b=Math.sqrt(c-a*a);
            //判定其是否为整数
            if(b==(int)b){
                return true;
            }
        }
        return false;
    }
}

复杂度分析

  • 时间复杂度:O(根号c)

    • 枚举 a的时间复杂度为O(根号c)
      对于每个 a的值,可在 O(1)的时间内寻找 b。
  • 空间复杂度:O(1)。

方法二:双指针

假设 a≤b。初始时 a=0,b =根号c
,进行如下操作:

  • 如果 a2 + b2 = c,找到一个解,返回 true;
  • 如果 a2 + b2 <c,将 a的值加 111,继续查找;
  • 如果 a2 + b2 >c,将 b 的值减 111,继续查找。

当 a=b时,结束查找
此时如果仍然没有找到整数 a 和 b 满足 a2 + b2 = c,
则说明不存在题目要求的解,返回false。

class Solution {
    public boolean judgeSquareSum(int c) {
        long left = 0;
        long right = (long) Math.sqrt(c);
        while (left <= right) {
            long sum = left * left + right * right;
            if (sum == c) {
                return true;
            } else if (sum > c) {
                right--;
            } else {
                left++;
            }
        }
        return false;
        // int a=0;long b=(int)Math.sqrt(c);  
        // while(a<=b){
        //     if(a*a+b*b==c){
        //         return true;
        //     }else if(a*a+b*b<c){
        //         a++;
        //     }else{
        //         b--;
        //     }  
        // }
        //  return false;
    }
}

复杂度分析

  • 时间复杂度:O(根号c)
    • 最坏情况下 a 和 b一共枚举了 0 到根号c里的所有整数。
  • 空间复杂度:O(1)。

方法三:费马平方和定理

一个非负整数 c如果能够表示为两个整数的平方和,当且仅当 c 的所有形如 4k+3 的质因子的幂均为偶数。

证明:https://wstein.org/edu/124/lectures/lecture21/lecture21/node2.html

  • 对c进行质因数分解,
  • 判断所有的关于4k+3的质因子的幂是否均为偶数
class Solution { 
	public boolean judgeSquareSum(int c) { 
		for (int base = 2; base * base <= c; base++) { 
			// 如果不是因子,枚举下一个 
			if (c % base != 0) { 
				continue;
			}
			// 计算 base 的幂 
 			int exp = 0; 
			while (c % base == 0) {
 				c /= base; 
 				exp++; 
 			} 
  			// 根据 Sum of two squares theorem 验证 
  			if (base % 4 == 3 && exp % 2 != 0) { 
  			return false; 
  			} 
  		}  
  		// 例如 11 这样的用例,由于上面的 for 循环里 base * base <= c ,base == 11 的时候不会进入循环体 
  		// 因此在退出循环以后需要再做一次判断 
  		return c % 4 != 3; 
  	} 
}

复杂度分析

  • 时间复杂度:O(根号c)。

  • 空间复杂度:O(1)。
    参考链接:https://leetcode-cn.com/problems/sum-of-square-numbers/solution/shuang-zhi-zhen-de-ben-zhi-er-wei-ju-zhe-ebn3/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值