[New Star] 二分法

          我一开始是看完了大话数据结构(好书!! 推荐),基本了解了二分查找法,但不能够熟悉他 ,所以就去了leetcode刷题,刷题路线是跟着代码随想录的(好网站),做的第一道题是   704. 二分查找https://leetcode-cn.com/problems/binary-search/

[New Star] 二分法_第1张图片

  一开始没有使用到二分查找 ,直接暴力了,应该创建mid

class Solution {
public int search(int[] nums, int target) {
for(int  i = 0;i

理解二分法的思想,正确做法:

​
class Solution {
   public int search(int[] nums, int target) {
   int low = 0, high = nums.length - 1;
 while (low <= high) {
int mid = (high - low) / 2 + low;
int num = nums[mid];
if (num == target) {
return mid;
} else if (num > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
}

​

第二题是35. 搜索插入位置https://leetcode-cn.com/problems/search-insert-position/

 [New Star] 二分法_第2张图片

他考察的还是二分法,但是 如果值不存在, 需要插入值保证有序

学到新知识点:要在二分查找的过程中,保持不变量,这也就是循环不变量,码中定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要)

当他不存在时,high 总会在他的前面,不管是low变大还是high变小

 这是我的做法:

​class Solution {
    public int searchInsert(int[] nums, int target) {
     int  mid,low = 0,high = nums.length -1;
int   n = 0;
    while (low <= high){
      mid = low +(high -low ) /2;
    if(target  nums[mid])
       low = mid +1;
       else 
       return   mid;
   n= mid;
  }
return  high +1;
    }
}

 而第三题是我的噩梦

34. 在排序数组中查找元素的第一个和最后一个位置https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/

题目确实短,却要了我的命!!!!

但却让我掌握了二分法!!

 让我注意到了二分法的边界问题。

这个博主讲的很好推荐!

【二分查找】详细图解_Charon_cc的博客-CSDN博客_二分查找

[New Star] 二分法_第3张图片

函数分别是寻找左边界和右边界:

我补充是:

二分法最重要的两个点:

  • while循环中 left 和 right 的关系,到底是 left <= right 还是 left < right
  • 迭代过程中 middle 和 right 的关系,到底是 right = middle - 1 还是 right = middle

第一种写法(左闭右闭)

• 循环条件要使用while(left <= right),因为当(left == right)这种情况发生的时候,得到的结果是有意义的

循环条件修改为while (left < left)

•还未找到target的情况下算法就跳出了循环,返回 -1

右边界等于left

因为只有num >target时,范围会向左缩,但小于或等于时left会一直右移,移到刚刚大于target值的地方

同理左边界

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int  left = leftSearch(nums,target);
        int  right = rightSearch(nums,target);
        if(left ==-2 ||right ==-2)  return  new int[]{-1,-1};
        if(right -left >1) return  new  int[]{left +1,right -1};
        return  new int[]{-1,-1}; 

    }

    public  int  leftSearch(int[] nums,int target){
        int mid,flag = -2,left = 0,right = nums.length -1;
        while(left <=  right){
            mid = (right +left)/2;
            if(nums[mid]target){
                right = mid -1;
            }else{
              left =  mid +1;
              flag = left;

            }
        }
        return   flag;
    }

}

第三第四题差不多

[New Star] 二分法_第4张图片

 69.x 的平方根

一开始我想创建数组,然后再用二分查找,

其实用两个数的范围,就可以用二分查找,

0 <= x <= 231 - 1

还要注意变量的范围 ,需要扩大范围

class Solution {
    public int mySqrt(int x) {
        int l = 0, r = x, ans = -1;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if ((long) mid * mid <= x) {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return ans;
    }
}

[New Star] 二分法_第5张图片

class Solution {
    public boolean isPerfectSquare(int num) {
int  low = 1 ,high = num,mid = 0,n = 0;
while(low<=high){
    mid =(high +low) /2;
    if(num <(long)mid*mid){
        high = mid -1;

    }else if( num >(long)mid*mid){
        low = mid+1;
    }else if(num == (long )mid *mid)
    return true;
}
return false;
    }
}

最后谢谢大家!!借用海明威激励自己!!!

一个人并不是生来要给打败的,你尽可以把他消灭掉,可就是打不败他。 --海明威

你可能感兴趣的:(java)