「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
633. 平方数之和
给定一个非负整数 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
方法一:通过开根来求解
思路
在理解题目意思以后,我们可以得出a * a <= c 且b * b <= c 这里我们就需要从0开始循环,在 0<=a && a * a <= c 的范围之间,去寻找一个合适的值。 通过c - a * a 我们可以得到b * b的值,要求b 我们需要开平方。使用Math.sqrt来处理 得到的结果必须是一个整数,如果带有小数点则不是我们需要的 所以b === parseInt(b)如果满足条件则返回true,否则继续循环直到结束未找到则返回false
var judgeSquareSum = function (c) {
for (let a = 0; a * a <= c; a++) {
const b = Math.sqrt(c - a * a);
if (b === parseInt(b)) {
return true;
}
}
return false;
}
方法二: 双指针
思路
另外一种思路就是通过双指针的方式:
我们声明两个数left和right满足left<=right,假设 total = left * left + right * right,如果c存在两个数的平方和相加等于c,那么total===c
接下来我们让left从0开始,right从Math.floor(Math.sqrt(c))开始(为什么想下去取整,如果向上的话就肯定导致total大于c了)
然后跟据total的结果,让指针逐步向中间靠拢,
- 假设right在正确的值,那么left从0开始必然是偏小,需要left逐渐增大
- 假设left在正确的位置,那么right从最大值开始必然是偏大,需要right逐渐减小
由上可得,如果total>c 那么我们就让right--
如果total<c 那么我们就让left++
一直循环,重复以上步骤,
- 如果total===c:那么直接返回true
- 如果当left===right的时候如果total还是!==c: 那就证明不存这样的left和right 在函数末尾返回false
/**
* @param {number} c
* @return {boolean}
*/
var judgeSquareSum = function (c) {
var left = 0;
var right = Math.floor(Math.sqrt(c))
while(left<=right){
var total = left*left+right*right
if(total===c){
return true
}
if(total>c){
right--
}
if(total<c){
left++
}
}
return false
};