LeetCode0069-平方根排序

二分查找

一句话:干就完了

题目

给你一个非负整数 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的最大数

posted @ 2021-10-30 10:48  RetenQ  阅读(26)  评论(0编辑  收藏  举报