[路飞]_leetcode刷题_633. 平方数之和

73 阅读1分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

题目

633. 平方数之和

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

示例 1:

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

示例 2:

输入:c = 3
输出:false

解法一

暴力解法

思路

在[0,c]中双循环遍历,将任意两个数组合,判断平方和是否等于c。

这个代码我都不想尝试,必然超时,想都不用想,抬走,下一位。

解法二

缩小遍历范围,单循环。

思路

想一想,解法一的遍历范围是否可以缩小?

a2 + b2 = c,那是不是在[0,c\sqrt{c}]范围内找就可以了。

另外,我们选定a之后,有必要再去遍历取b,求两者的平方和等于c?

是不是可以直接用c - a2 ,看看结果是不是整数就ok了?

代码如下

/**
 * @param {number} c
 * @return {boolean}
 */
var judgeSquareSum = function(c) {
    
    for(let a=0;a*a<=c;a++){
        let b = Math.sqrt(c-a*a);
        if(b == parseInt(b)){
            return true;
        }
    }
    return false;
};

复杂度分析

时间复杂度:O(c\sqrt{c})

空间复杂度:O(1)

解法三

双指针

思路

和求盛水最多的容器那题思路很像。

我们先求出b可能的最大值,即 b_max = Math.floor(c\sqrt{c})

然后我们让a从0开始往后走,b从当前这个b_max开始往前走,逻辑如下

  1. 如果a2 + b2 > c,则让b往前走一格,即b--
    • 这么思考,此时的a为最小值,如果满足这个条件,那么此时的这个b与任何一个值合作,结果都大于c,那么这个b等于不可能起作用,直接给它作废。
  2. 如果a2 + b2 < c,则让a往后走一格,即a++
    • 因为,此时的b为最大值,如果满足这个条件,此时的a与任何一个值合作,结果都小于c,那么这个a直接作废。
  3. 后面一直按照这个逻辑去双指针夹逼,直到a与b相等,如果还无法满足等于,则返回false
  4. 如果满足a2 + b2 = c,则返回true。

代码如下

/**
 * @param {number} c
 * @return {boolean}
 */
var judgeSquareSum = function(c) {
    let b = Math.floor(Math.sqrt(c));
    let a = 0;
    while(a<=b){
        if(a*a + b*b > c){
            b--;
        }else if(a*a + b*b < c){
            a++;
        }else{
            return true
        }
    }
    return false;
};

复杂度分析

时间复杂度:O(c\sqrt{c}),实际只有c\sqrt{c}/2。

空间复杂度:O(1)