目录
题目规则
编写一个函数,实现完全平方数的判断,例如F(16) 是完全平方数,因为16是4的平方。
题目分析
首先针对完全平方数进行一个回顾:完全平方指用一个整数乘以自己例如1*1,2*2,3*3等,依此类推。若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。完全平方数是非负数,而一个完全平方数的项有两个。
由此可知,一个数值x的完全平方数是一个正整数n的平方,同时这个n 一定是存在区间[1, x]中的一个数值,如果在这个区间中没有n,则该数值不是一个完全平方数,那么根据这个区间,我们可以构造出二分查找的左右边界,下面开始实现下。
题目作答
使用 进行解题
上面说到,区间[1, x]中,一定有一个数值的平方是等于 x 的,因此可以将1与x作为二分边界,边界中间的基准数进行平方运算,判断是否与x相等。
- 构建左右区间
- 获取到区间中间数值(mid)
- 获取到num^2 的形式(x)
- 判断x与mid之间的关系,根据不同的关系返回不同结果
- 如果 x == mid 满足数学逻辑,直接将true返回出去
- 如果 x > mid 不满足数学逻辑,同时x较大,说明mid较大,应将右区间边界缩小
- 如果 x < mid 不满足数学逻辑,同时x较小,说明mid较小,应将左区间边界缩小
public boolean isPerfectSquare(int num) {
if (num == 1) return true;
int l = 0, r = num, backL = -1, backR = -1;
while ((backL != l || backR != r) && l < r) {
int mid = ((r - l) >> 1) + l;
int midNumber = mid * mid;
backL = l;
backR = r;
if (midNumber < 0){
r = mid;
continue;
}
if (midNumber == num) return true;
else if (midNumber < num) l = mid;
else r = mid;
}
return false;
}
但是这样的代码有一个小隐患,在计算机中,一个数值的存储是有上限的,如果一个数值过大,其平方数将会体现出爆炸性的增长,这种增长在计算机中会数值溢出,因此还有第二种解法,使用除法进行完全平方数值的判断。
使用 作答
我们思考下,针对一个完全平方数值,除法中一个特点如下所示
例如 9 是一个完全平方数,所以9 / 3 的结果还是3,这很符合我们的需求,接下来将该公式带入到二分查找的中间值中。
- 构建左右区间
- 获取到区间中间数值(mid)
- 获取到num / mid 的形式(x)
- 判断x与mid之间的关系,根据不同的关系返回不同结果
- 如果 x == mid 满足数学逻辑,直接将true返回出去
- 如果 x < mid 不满足数学逻辑,同时x较小,说明mid较大,应将右区间边界缩小
- 如果 x > mid 不满足数学逻辑,同时x较大,说明mid较小,应将左区间边界缩小
public boolean isPerfectSquare(int num) {
if (num == 1) return true;
int l = 0, r = num, backL = -1, backR = -1;
while ((backL != l || backR != r) && l < r) {
int mid = ((r - l) >> 1) + l;
double midNumber = num / (double) mid;
backL = l;
backR = r;
if (midNumber == mid) return true;
else if (midNumber < mid) r = mid;
else l = mid;
}
return false;
}