二分查找
一句话:干就完了
题目
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
题解
写了二分查找就老老实实用二分
class Solution {
public int mySqrt(int x) {
int result = -1 ;
int left = 0 ;
int right = x ; //不用是x/2
int middle = 0 ;
while(left<=right){
middle = left + (right - left)/2 ;
//这样子取平均值不会溢出
if((long)middle*middle <= x){
//使用long来比较同样是为了防止溢出
//当然,反过来使用middle和x/middle也可以,不过主要middle的值哦
result = middle ;
left = middle + 1 ;
}else{
right = middle - 1;
}
}
return result ;
}
}
很基础的题目很基础的解答,主要注重的地方依旧是参数更新
首先是middle*middle <= x
这一部分,这里有两个注意点:
首先是无论如何,只要到这一步就有的result = middle ;
我们根据题意,很容易得到,只有middle*middle <= x
的答案才是符合题意的
其次是参数更新,也就是left = middle + 1 ;这里稍后一起讲
先看循环条件while(left<=right)
也就是说即使left和right重合时也会继续
那会死循环吗?铁不会啊,你在循环中就会执行参数更新,你拥挤到left和right重合的情况,middle一定也是二者其中一位
而在下一次更新后,不是left+1就是right-1,直接打破循环
那么回过头来,怎么保证result一定是我们想要的值呢?
接前文,二分实际上就是一个不断查找的过程,左方的结果越来越大,而右方则是越来越小,直到我们找到这个数
记住,左方的结果越来越大,而右方则是越来越小,有的地方要利用这里进行判断
在这里,我们的题目不允许我们的result大于x的平方根,即使它非常非常非常接近
于是我们要找的数实质上是:
保持其平方小于等于x的最大数