Note: all the following contents are from personal superficial understanding of the use of binary search, for personal reference only! Don't spray if you don't like it. Welcome to correct it!
1, The situations suitable for binary search are divided into two categories:
1. Obvious conditions:
The array is ordered and clearly tells you that the elements of the array will not be repeated.
In this case, it must be possible to find with two points.
2. Implied conditions:
The Title Description array is:
Non ascending (meaning that the array is in overall descending order, and the array elements are allowed to be repeated);
For example: int[] array={9,8,8,6,5,4,3,2,1}
Non descending (meaning that the array is in ascending order as a whole, and the array elements are allowed to repeat);
For example: int [] array={0,1,1,2,3,4,5,6,6,6,7}
In this case, one of the situations I have encountered is that the following "example 2" can be searched with two points.
2, Two binary search methods:
1. Left closed right closed interval type:
Right is the length of the array - 1, that is, the array subscript may access right;
left is 0 subscript;
In this case, the searched target may be a boundary case, so the loop condition of while() is left < = right
Moreover, when your array [mid] > target, there is no target on the target and on the right side of the target, and the boundary of the interval remains unchanged, that is, it is still left closed and right closed,
I.e. = right=mid-1;
When your array [mid] < target, there is no target on the target and the left side of the target, and the boundary of the interval remains unchanged. It is still a left closed interval and a right closed interval,
That is, = left=mid+1;
When array[mid]=target is satisfied, mid is the subscript of target, that is, mid is returned;
2. Left closed right open section type:
Right is the length of the array, that is, the array subscript cannot access right;
left is 0 subscript;
In this case, the searched target cannot be a boundary case, so the loop condition of while() is left < right
Moreover, when your array [mid] > target, there is no target on the target and the right side of the target, and the boundary of the interval remains unchanged, that is, it is still a left closed and right open interval,
That is, = right=mid;
When your array [mid] < target, there is no target on the left of target and target, and the boundary of the interval remains unchanged. It is still a left closed and right open interval,
That is, = left=mid+1;
When array[mid]=target is satisfied, mid is the subscript of target, that is, mid is returned;
3. Specific examples:
connect:
https://leetcode-cn.com/problems/binary-search/
Question on force deduction: binary search
Given an n-element ordered (ascending) integer array nums and a target value target, write a function to search the target in nums. If the target value exists, return the subscript, otherwise return - 1.
input: nums = [-1,0,3,5,9,12], target = 9 output: 4 explain: 9 Appear in nums Middle and subscript 4
Left closed right closed solution:
class Solution { public static int search(int[] nums, int target) { int left=0; int right=nums.length-1; while(left<=right){ int mid=left+(right-left)/2; if(nums[mid]>target){ right=mid-1; }else if(nums[mid]<target){ left=mid+1; }else{ return mid; } } return -1; } }
Left closed right open solution:
class Solution { public static int search(int[] nums, int target) { int left=0; int right=nums.length; // Notice that there's no change here - 1 while(left<right){ // The cyclic condition here has no equal sign int mid=left+(right-left)/2; if(nums[mid]>target){ right=mid;//The array length value that cannot be obtained here is not - 1; }else if(nums[mid]<target){ left=mid+1; }else{ return mid; } } return -1; } }
3, Two practical questions for binary search:
1. Corresponding to 1 in 1:
connect:
https://leetcode-cn.com/problems/search-insert-position/
Title:
Given a sort array and a target value, find the target value in the array and return its index. If the target value does not exist in the array, returns the position where it will be inserted in order.
You must use an algorithm with a time complexity of O(log n).
Use case:
Input: num = [1,3,5,6], target = 5 Output: 2
Input: num = [1,3,5,6], target = 2 Output: 1
Input: num = [1,3,5,6], target = 0 Output: 0
Left closed right closed solution:
class Solution { public static int searchInsert(int[] nums, int target) { int l=0; int r=nums.length-1; //Left closed right closed interval. while(l<=r){ int mid=l+(r-l)/2; if(nums[mid]>target){ r=mid-1; }else if(nums[mid]<target){ l=mid+1; }else{ return mid; // Handled the case that the target exists in the array } } return r+1; // Processed 1 Target before array, 2 Target is inserted into the array. 3.target is at the last edge of the array. } }
Left closed right open solution:
class Solution { public static int searchInsert(int[] nums, int target) { //Dichotomy the second method; int left=0; int right=nums.length; //Left closed and open section; while(left<right){ int mid=left+(right-left)/2; if(nums[mid]>target){ right=mid; }else if(nums[mid]<target){ left=mid+1; }else{ return mid; } } return right; } }
2. Corresponding to a question:
connect:
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
Title:
Given an integer array nums arranged in ascending order and a target value target. Find the start and end positions of the given target value in the array.
If the target value target does not exist in the array, return [- 1, - 1].
Advanced:
Can you design and implement an algorithm with time complexity of O(log n) to solve this problem?
Use case:
Input:nums = [5,7,7,8,8,10], target = 8 Output:[3,4]
Input:nums = [5,7,7,8,8,10], target = 6 Output:[-1,-1]
Left closed and closed solution:
class Solution { //Find the first > = target first //Find the first > target //The first solution public int[] searchRange(int[] nums, int target) { int l=searchFirst(nums,target); int r=searchFirst(nums,target+1); if(l==nums.length||nums[l]!=target){ return new int[]{-1,-1}; } return new int[]{l,r-1}; } public int searchFirst(int[] nums,int target){ int l=0; int r=nums.length; while(l<r){ int mid=l+(r-l)/2; if(nums[mid]>=target){ r=mid; }else{ l=mid+1; } } return l; } }
Left closed right open solution:
class Solution { //Find the first > = target first //Find the first > target //The second solution public int[] searchRange(int[] nums, int target) { int l=searchFirst(nums,target); int r=searchFirst(nums,target+1); if(l==nums.length||nums[l]!=target){ return new int[]{-1,-1}; } return new int[]{l,r-1}; } public int searchFirst(int[] nums,int target){ int l=0; int r=nums.length-1;// It's changed here while(l<=r){ int mid=l+(r-l)/2; if(nums[mid]>=target){ r=mid-1;//It's changed here }else{ l=mid+1; } } return l; } }
IV. summary:
The personal summary of binary search of array is over. You are welcome to point out the errors. Once again, this blog is only a personal superficial understanding and summary. Don't spray if you don't like it! Don't spray if you don't like it! Don't spray if you don't like it! Say important things three times!!!
If you think this blog can help you, please pay attention and support. Thank you very much