有效的完全平方数
给一个正整数 num 。如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
完全平方数 是一个可以写成某个整数的平方的整数。换句话说,它可以写成某个整数和自身的乘积。
不能使用任何内置的库函数,如 sqrt 。
示例 1:
输入:num = 16
输出:true
解释:返回 true ,因为 4 * 4 = 16 且 4 是一个整数。
示例 2:
输入:num = 14
输出:false
解释:返回 false ,因为 3.742 * 3.742 = 14 但 3.742 不是一个整数。
提示:
0 <= x <= 2^31 - 1
思路:
定义target在左闭右闭的区间里,[left,right]。
设立两个指针left和right。
middle=(left+right)/2。
如果判断num等于middle*middle或num在middle*middle的左边,则更新右指针为middle。
否则num就在middle*middle的右边,则更新左指针为middle。
循环到left-right<=1,循环终止。
最后得出的答案num的平方根取整后的结果就是left。
如果left*left==num,则num是完全平方数,反之则不是完全平方数
代码:
class Solution
{
public:
bool isPerfectSquare(int num)
{
// 二分查找区间为[0,2^31-1]
int left = 0, right = pow(2, 31) - 1;
while (right - left > 1)
{
double middle = left + ((right - left) >> 1);
if (middle * middle > num)
{
right = middle;
}
else
{
left = middle;
}
}
return left * left == num ? true : false;
}
};
解释:
left + ((right - left) >> 1)==(left + right) / 2
因为left+right可能溢出,(right-left)使用减法不会超出最大的整型范畴,所以使用第一种方法可以防止溢出。
>>是右移运算符,右移一位等于除以2,右移n位等于除以2的n次方。
middle取值必须为double,如果为int,存在溢出的可能性。