专题二分法 力扣69求x的平方根

回来刷专题了

思路

套的二分查找,[0,x]查找mid,如果

  1. m i d 2 < = x mid^{2}<=x mid2<=x并且 ( m i d + 1 ) 2 > x (mid+1)^{2}>x (mid+1)2>x,返回mid
  2. m i d 2 < x mid^{2}<x mid2<x并且 ( m i d + 1 ) 2 < = x (mid+1)^{2}<=x (mid+1)2<=x
    这里要分情况讨论,
    如果 ( m i d + 1 ) 2 = x (mid+1)^{2}=x (mid+1)2=x,说明mid+1是要找的值,否则说明区间找小了,要往大了找,将left改成mid+1,区间变成[mid+1,left]
  3. m i d 2 > x mid^{2}>x mid2>x
    这种情况比较好说就是直接找大了,可以不考虑mid+1,因为更大了,直接往小了再找,right改成mid-1,区间变成[mid+1,right]

代码实现

private static int mySqrt(int x) {
        long s=(long)x;//第一次提交发现会有越界异常,改成long了
        long left=0;
        long right=x;
        while (left<=right){
            long mid =left+(right-left)/2;
            if ((mid*mid<=x)&&((mid+1)*(mid+1)>x))//憨憨直接考虑小数了,mid平方<=目标值
                //或者mid+1方>目标值,就返回这个值
                return (int)mid;
            else if ((mid*mid<x)&&((mid+1)*(mid+1)<=x)){
                if ((mid+1)*(mid+1)==x)//如果mid比目标值小但是+1正好等于目标
                    return (int)mid+1;//返回mid+1
                left=mid+1;//不然就是区间小了,向右在找
            }
            else if (mid*mid>x){//大了就好说了,直接改小区间,向左边找
                right=mid-1;
            }

        }
        return -1;
    }

优化

看了大佬的代码之后发现自己写的有点垃圾

  1. 区间优化
    整型int的最大值是 2 32 − 1 2^{32} - 1 2321(说明不会取到任何超过这个数的值),对它开平方约等于46340,任何大于这个数的整数的平方都会越界,所以我们要做好约束。
  2. 这个题就是一个找最右边的满足条件的值
    简单抽象一下,nums数组就是 [0,1,2,3,4,…,x] target 就是 x 的平方根。以题目的 8 为例,我们 先不考虑结果只保留整数的部分最后再将小数部分去掉即可。·这么来看,2,…,2.82841,2.82842,… 都是符合的。由于需要返回不带小数的,那不就是返回 最左边的满足条件的值 么?但是这种算法比较复杂,原因在于计算误差,比如题目限定了 1 0 − 5 10 ^{-5} 105 以内的误差都可以,那么是可以的。
    仍然以 8 为例, 我们想要在 1,2,3,4,5… (注意我这里不考虑小数了)找满足条件的 ans,使得 a n s 2 ans ^{ 2} ans2 刚好小于等于 8,也就是找所有满足 a n s 2 ans ^{ 2} ans2 <= 8 的最大值,也就是 找最右边的满足条件的值 ,这里的条件就是 <= 8。

大佬代码

class Solution {
    public int mySqrt(int x) {
        if(x==1)
            return 1;    
        int left=0;
        int right=46340;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(mid*mid>x){
                right=mid-1;
            }else if(mid*mid<x){
                left=mid+1;
            }else{
                return mid;
            }
        }
        return right;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值