题目要求
给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。
示例 1:
输入:c = 5
输出:true
解释:1 * 1 + 2 * 2 = 5
示例 2:输入:c = 3
输出:false
提示:
0 <= c <= 231 - 1
这道题目其实和Leetcode 167.两数之和Ⅱ-输入有序数组的思路一样,只不过将数组的元素换成了整数的平方,解题思路和想法以及为什么没有信息损耗都是一样的解释,但是唯一要注意的问题就是代码中符号溢出的问题,当输入的数数字非常大时,右指针肯动不会出现该情况,左指针也不会,就是左指针和右指针相加的时候会导致符号溢出,所以要将num和l或者r设置为long型的元素。
但是我有个地方搞不明白,就是当我不设置中间变量的时候,while循环中的else里面找到了该数字就直接退出循环 return true,最后while循环结束还是没找到的话return false的最后时间是3ms。但是如果设置一个中间变量flag初始化为false,当while循环里进入else,就将flag设置为true,然后break退出循环,再将flag给return给函数返回值,此时的时间为0ms。归根结底,这两种思路没什么区别,但是为什么会有时间上的相差呢,可能是leetcode上的时间并不是所有的都很好,因为我有时候用比较差的代码跑出的时间复杂度都比较小,我并不是很明白,如果有人能够指出并且相互交流的话那么十分感谢。
class Solution {
public:
bool judgeSquareSum(int c)
{
//sqtr函数会取小数,所以可以用int函数来对得出的结果数字进行向下取整操作
int r = int(sqrt(c));
//为什么r也会存在数字溢出的情况,r不是c的开根号吗,按道理来说,输入的c是int型的,r应该用int型就够了
//应该是C++在对两个类型相加的时候会自动进行"精度对齐",例如当int类型和long类型相加的时候
//C++会自动将int类型的数字转换为long类型再相加,如果是单纯的两个int类型相加就会导致符号溢出问题
long l = 0, num = 0;
bool flag = false;
while(l <= r)
{
//是不是会存在数组越界的问题,但是按道理来说都不会超过c的值
num = l*l + r*r;
if(num < c)
{
l++;
}
else if(num > c)
{
r--;
}
else
{
// return true;
flag = true;
break;
}
}
//搞不清楚的一个问题是,为什么用一个中间变量flag来保存最后的值返回会比我直接用false和true返回时间来的快???
return flag;
}
};
以上代码思路仅个人观点,如果有更好的思路和想法,欢迎指正以及相互交流,相互进步,谢谢大家