携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
一、题目描述:
给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
进阶:
不要 使用任何内置的库函数,如 sqrt 。
示例 1:
输入:num = 16
输出:true
示例 2:
输入:num = 14
输出:false
提示:
- 1 <= num <= 2^31 - 1
二、思路分析:
二分法的变形
mid = l + (r - l) / 2 防止溢出。
(l + r) / 2不通过, 因为有个样例是2147483647, 加1就溢出, 很恶心。
但 r 取 num/2 就没这个问题了, 二分收敛速度很快其实差别不大。注意就行。
这个题目就有一点需要注意, 即else if(mid == num / mid && mid * mid == num) return true;
在mid == num / mid 时若mid * mid == num, 那它自然就是完全平方数。
否则的话只满足有些mid只能满足mid == num / mid。比如5/2 = 2。但它不是完全平方数。返回false。
三、AC 代码:
class Solution {
public:
bool isPerfectSquare(int num) {
if(num == 1) return true;
int l = 1, r = num, mid;
while(l <= r){
mid = l + (r - l) / 2;
if(mid < num / mid) l = mid + 1;
else if(mid > num / mid) r = mid - 1;
else if(mid == num / mid && mid * mid == num) return true;
else return false;
}
return false;
}
};
四、总结:
有点类似于第69题,求x的平方根,都是利用二分查找的方式进行排除,退出二分时如果left^2==num,那么表明num是完全平方数,否则返回false。
五、参考:
执行用时 : 0 ms , 在所有 C++ 提交中击败了 100.00% 的用户 - 有效的完全平方数 - 力扣(LeetCode)