二分查找的流程:

1.确定二分的边界

2.编写二分的代码框架

3.设计一个check性质

4.判断一下区间如何更新

5.如果更新方式写的是l=mid,r=mid-1,那么就在算mid的时候+1

 1 二分的模板:
bool check(int x) {/* ... */} // 检查x是否满足某种性质 2 //求第二个线段的起点 3 // 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用: 4 int bsearch_1(int l, int r) 5 { 6 while (l < r) 7 { 8 int mid = l + r >> 1; 9 if (check(mid)) r = mid; // check()判断mid是否满足性质 10 else l = mid + 1; 11 } 12 return l; 13 } 14 // 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
//求第一个线段的终点
15 int bsearch_2(int l, int r) 16 { 17 while (l < r) 18 { 19 int mid = l + r + 1 >> 1; 20 if (check(mid)) l = mid; 21 else r = mid - 1; 22 } 23 return l; 24 } 25 26

LEETCODE35.

 

 

 

class Solution {
    public int searchInsert(int[] nums, int target) {
        if(nums.length==0) return 0;
        if(target>nums[nums.length-1]) return nums.length;
        int  r=nums.length-1;
        int l=0;
        while(l<r){
            int mid=l+r>>1;
            if( nums[mid]>=target) r=mid;
            else l=mid+1;
        }
        return l;
    }
}

 

 

 

 1 class Solution {
 2     public int mySqrt(int x) {
 3         int l=0; int r=x;
 4         while(l<r){
 5             int mid=l+r>>1;
 6             if(mid<=x/mid) r=mid;
 7             else l=mid+1;
 8         }
 9         return l;
10     }
11 }

 

 

 

 1 class Solution {
 2     public int[] searchRange(int[] nums, int target) {
 3         if(nums.length==0) return new int[]{-1, -1};
 4       //先找出初始位置,nums[mid]>=target,也就是第二条线段的起点,用模板一
 5       int l=0,r=nums.length-1;
 6       while(l<r){
 7           int mid=l+r>>1;
 8           if(nums[mid]>=target) r=mid;
 9           else l=mid+1;
10       }
11       if(nums[r]!=target) return new int[]{-1, -1};
12       //再找出终止位置,nums[mid]<=target,也就是第一条线段的终点,用模板二
13       int l1=0,r1=nums.length-1;
14       int start=l;
15       while(l1<r1){
16           int mid=l1+r1+1/2;
17           if(nums[mid]<=target) l1=mid;
18           else r1=mid-1;
19       }
20       int end=r1;
21       return new int[]{start,end};
22 }
23 }

 

 

 

 

 

 

 1 class Solution {
 2     public boolean searchMatrix(int[][] matrix, int target) {
 3         //matrix[mid/m][mid%m]>=target,想找的就是第二条线段的起点,用模板一
 4         if(matrix.length==0||matrix[0].length==0) return false;
 5         int n=matrix.length;
 6         int m=matrix[0].length;
 7         int l=0;int r=m*n-1;
 8         while(l<r){
 9             int mid=l+r>>1;
10             if(matrix[mid/m][mid%m]>=target) r=mid;
11             else l=mid+1;
12         }
13         return matrix[r/m][r%m]==target;
14     }
15 }

 

 

class Solution {
    public int findMin(int[] nums) {
        int l=0,r=nums.length-1;
        //一个y=x的函数切成两半,找到第二段线段的起点,用模板一
        while(l<r){
            int mid=l+r>>1;
            if(nums[mid]<=nums[nums.length-1]) r=mid;
            else l=mid+1; 
        }
        return nums[l];
    }
}

 

 

 

 1 /* The isBadVersion API is defined in the parent class VersionControl.
 2       boolean isBadVersion(int version); */
 3 
 4 public class Solution extends VersionControl {
 5     public int firstBadVersion(int n) {
 6         int l=0,r=n;
 7         //找第二个线段的起点,用模板一
 8         while(l<r){
 9             int mid=l+(r-l)/2;//防止溢出
10             if(isBadVersion(mid)==true) r=mid;
11             else l=mid+1;
12         }
13         return l;
14     }
15 }

 

 

 1 class Solution {
 2     public int search(int[] nums, int target) {
 3         //先确定在旋转后的函数的哪段,再对这一段进行二分
 4         int n=nums.length;
 5         int l=0;
 6         int r=n-1;
 7         if(n==0) return -1;
 8         //找第二个线段的起点
 9         while(l<r){
10             int mid=l+r>>1;
11             if(nums[mid]<nums[n-1]) r=mid;
12             else l=mid+1;
13         }
14         if(target<=nums[n-1]) r=n-1;
15         else {l=0; r--;}
16         while(l<r){
17             int mid=l+r>>1;
18             if(nums[mid]>=target) r=mid;
19             else l=mid+1;
20         }
21         if(nums[l]==target) return l;
22         return -1;
23         
24     }
25 }

 

 

 

class Solution {
    public int search(int[] nums, int target) {
         int n = nums.length;
        if (n == 0) {
            return -1;
        }
        if (n == 1) {
            return nums[0] == target ? 0 : -1;
        }
        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] == target) {
                return mid;
            }
            if (nums[0] <= nums[mid]) {
                if (nums[0] <= target && target < nums[mid]) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[n - 1]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
        }
        return -1;
 
    }
}

 

 

 1 class Solution {
 2     public int findDuplicate(int[] nums) {
 3       int n = nums.length;
 4         int l = 1, r = n - 1, ans = -1;
 5         while (l <= r) {
 6             int mid = (l + r) >> 1;
 7             int cnt = 0;
 8             for (int i = 0; i < n; ++i) {
 9                 if (nums[i] <= mid) {
10                     cnt++;
11                 }
12             }
13             if (cnt <= mid) {
14                 l = mid + 1;
15             } else {
16                 r = mid - 1;
17                 ans = mid;
18             }
19         }
20         return ans;
21 
22  
23     }
24 }

 

 

 1 class Solution {
 2     public int hIndex(int[] citations) {
 3         int n=citations.length;
 4         int l=0;
 5         int r=n ;
 6         while(l<r){
 7             int mid=l+r+1>>1;
 8             if(citations[n-mid]>=mid) l=mid;
 9             else r=mid-1;
10         }
11         return r;
12     }
13 }

 

 posted on 2021-10-27 19:16  “樂·~  阅读(34)  评论(0编辑  收藏  举报