二分查找之leetcode69求开方+441摆硬币+540有序数组的 Single Element

leetcode 69

方法一:袖珍计算器算法

注意:

  • exp和log前面都要加上math,log
  • 最后判断要是<=而不是<
  • 最后两个int相乘机的用较大的long进行处理
  • 时空复杂度均为O(1)
class Solution {
    public int mySqrt(int x) {
        if(x==0) return 0;
        int res=(int)Math.exp(0.5*Math.log(x));//这里的Math不要忘记
        return (long)(res+1)*(res+1)<=x?(res+1):res;//这里的long也很容易写错,还有<=
    }
}

方法二:二分查找

  • 在循环条件为 l < h,如果 h = mid - 1,会错误跳过查找的数,例如对于数组 [1,2,3],要查找 1,最开始 l = 0,h = 2,mid = 1,判断 key < arr[mid] 执行 h = mid - 1 = 0,此时循环退出,直接把查找的数跳过了。
  • 比较奇怪的是二分法是如何找到,最合适的数值的呢?其实这里k是不可能出现在else里面的,但是左边的范围又是不断靠右,所以ans最后一次更新的值一定就是开方值
class Solution {
    public int mySqrt(int x) {
        int mid=0,l=0,r=x,ans=-1;//这里r=x-1是错误的
        while(l<=r){
            mid=l+(r-l)/2;
            if((long)mid*mid<=x) {//有乘积的时候记得用long
                ans=mid;
                l=mid+1;
            }else r=mid-1;//这两句的顺序不能反
            //其实这里k是不可能出现在else里面的
            //但是左边的范围又是不断靠右,所以ans最后一次更新的值一定就是开方值
        }
        return ans;
    }
}

猜你喜欢

转载自www.cnblogs.com/sjh-dora/p/12891721.html