「这是我参与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,]范围内找就可以了。
另外,我们选定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()
空间复杂度:O(1)
解法三
双指针
思路
和求盛水最多的容器那题思路很像。
我们先求出b可能的最大值,即 b_max = Math.floor()
然后我们让a从0开始往后走,b从当前这个b_max开始往前走,逻辑如下
- 如果a2 + b2 > c,则让b往前走一格,即b--
- 这么思考,此时的a为最小值,如果满足这个条件,那么此时的这个b与任何一个值合作,结果都大于c,那么这个b等于不可能起作用,直接给它作废。
- 如果a2 + b2 < c,则让a往后走一格,即a++
- 因为,此时的b为最大值,如果满足这个条件,此时的a与任何一个值合作,结果都小于c,那么这个a直接作废。
- 后面一直按照这个逻辑去双指针夹逼,直到a与b相等,如果还无法满足等于,则返回false
- 如果满足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(),实际只有/2。
空间复杂度:O(1)