It integrates several writing methods on Li buckle and the writing method of code Capriccio. Thank you!
Key points: define the interval clearly and keep it unchanged in the loop operation (loop invariant principle).
1, Number of binary search monotone arrays (no repetition)
1. Left closed right closed
int binarySearch(vector<int> &nums, int target){ int left = 0, right = nums.size()-1; while (left <= right){ int mid = left + right >> 1; if (nums[mid] > target){ right = mid -1; } else if (nums[mid] < target){ left = mid + 1; } else { return mid; } } return -1; }
For left closed and right closed intervals:
1. The judgment condition of while is < =. Under the condition of equal, the interval length is 1, which is meaningful.
2. Update left to mid+1 and right to mid-1.
3. Because it is right closed, the initial value of right is num.size () - 1.
2. Left closed right open
int binarySearch (vector<int> &nums, int target){ int left = 0, right = nums.size(); while (left < right){ int mid = left + right >> 1; if (nums[mid] > target){ right = mid; } else if (nums[mid] < target){ left = mid + 1; } else { return mid; } } return -1; }
Description of left closed right open interval:
one The judgment condition of while is <, because under the condition of equal to, because the interval is left closed and right open, the interval length is 0, which is meaningless.
2.left is updated to mid+1 and right is updated to mid (because the right is an open interval).
If the array contains target, the subscript is returned; otherwise, - 1 is returned.
3. Because it is opened on the right, the initial value of right is nums.size().
2, Bisecting the left and right boundaries of an interval
1. Left closed right closed
Right boundary between two zones
int binarySearch (vector<int> &nums, int target){ int left =0, right = nums.size() - 1; while(left <= right){ int mid = left + right >> 1; if (nums[mid] >= target) right = mid - 1; else left = mid + 1; } return left; }
After two points, left is the subscript of the first element greater than or equal to target, and right is the subscript of the last element less than target.
The left boundary of the interval is the subscript of the first element equal to target, so left is returned.
Left boundary between two zones:
int binarySearch (vector<int> &nums, int target){ int left = 0, right = nums.size() - 1; while (left <= right){ int mid = left + right >> 1; if (nums[mid] <= target) left = mid + 1; else right = mid - 1; } return right; }
After two points, right is the subscript of the last element less than or equal to target, and left is the subscript of the first element greater than target.
The right boundary of the interval is the subscript of the last element equal to target, so right is returned.
2. Left closed right open
Left boundary between two zones:
int binarySearch (vector<int> &nums, int target) { int left = 0, right = nums.size(); while (left < right) { int mid = left + right >> 1; if (nums[mid] >= target) right = mid; else right = mid + 1; } return right; }
After two points, left is equal to right, which is the subscript of the first element greater than or equal to target.
So you can return both left and right.
Right boundary between two zones:
int binarySearch (vector<int> &nums, int target) { int left = 0, right = nums.size(); while (left < right) { int mid = left + right >> 1; if (nums[mid] <= target) left = mid + 1; else right = mid; } return right - 1; }
After two points, left equals right, which is the lower edge + 1 of the last element equal to target.
So you should return left-1 or right-1.
Personal understanding: bisection is essentially bisecting the left and right boundaries of an interval. In fact, the left and right boundaries between two partitions can also be used to find a number in the array.
The use of binary arrays requires monotonicity.
The author's level is limited, welcome criticism and correction.