二分法
对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。
这就是我高中接触的二分法,最开始觉得这个方法秒啊!但是时间长之后也就啥也不记得了,等到自己学了计算机开始上手算法就发现这个二分查找的频率确实有点高,所以想要总结一下这个二分查找。
直接说题,由题出结论:
leetcode 69题:
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
首先是我最开始的想法,从0遍历到x/2,因为平方根一定是小于等于x/2,所以我开始敲代码,后来我在1、0、2这几个节点上面纠结了很长时间,后来我发现着根本就不对,后来我又想用栈来做,在遍历的时候如果i*i<=x就push,如果大于就返回栈顶元素。后来我发现这种方法,不光时间复杂度没有改变,空间复杂度还变大了。看了题解发现是二分查找,仔细看了以后才发现 真是秒啊!
1 class Solution { 2 public int mySqrt(int x) { 3 long left =0; 4 long right = (x>>>1)+1;//我又被这个>>>1给弄蒙蔽了,每次都忘记了这个位运算的意义 5 while(left < right){ 6 long mid = (left + right + 1)/2; 7 long num = mid * mid; 8 if(num > x){ 9 right = mid - 1 ; 10 }else{ 11 left = mid; 12 } 13 } 14 return (int)left; 15 } 16 }
我觉得最重要的就是寻找二分查找的边界,找到合适的边界就会找到捷径。