基本二分查找
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 |  long int binarySearch_basic(vector<int>& numbers, int target){
 if(numbers.size() <= 0) return -1;
 long int start = 0, end = numbers.size()-1, mid = 0;
 while(start <= end){
 mid = start + (end - start) / 2;
 if(target == numbers[mid]) return mid;
 else if(target < numbers[mid]) end = mid-1;
 else start = mid+1;
 }
 return -1;
 }
 
 | 
二分查找的时间复杂度是 $O(logn)$ , 二分查找里的边界条件有不同的写法:
1,朴素的二分查找,当 while 循环的条件中是 start<=end 时,在[start, end] 的闭区间上查找。end = mid -1; start = mid+1; 它最后一个循环是start = mid = end.
使用场景:基于二分查找的题目很多,但基本很多情况都是给排序好的数组之类的进行查找。
leecode34 二分查找第一与最后位置
主要是避免mid计算得到的还是start的位置,然后满足条件 start还是取mid,一直死循环。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 | 
 int binarySearch_hz_left(vector<int>& numbers, int target){
 if(numbers.size() <= 0) return -1;
 int start = 0, end = numbers.size(), mid = 0;
 while (start != end) {
 mid = start + (end - start) / 2;
 if (numbers[mid] >= target) {
 end = mid;
 } else {
 start = mid+1;
 }
 }
 if (start == numbers.size()) return -1;
 return numbers[start] == target ? start : -1;
 
 }
 
 
 
 
 int binarySearch_hz_right(vector<int>& numbers, int target){
 if(numbers.size() <= 0) return -1;
 int start = 0, end = numbers.size()-1, mid = 0;
 while (start != end) {
 mid = (start + end + 1) / 2;
 if (numbers[mid] <= target) {
 start = mid;
 } else {
 end = mid - 1;
 }
 }
 return numbers[start] == target ? start : -1;
 
 }
 
 | 
另外在leecode上看到的解析,做个小记录参考,主要还是用上面的写法吧,找右边界好记点。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | int searchRange_left_bound(vector<int>& nums, int target){if (nums.size() == 0) {
 return -1;
 }
 int start=0, end=nums.size();
 while (start < end) {
 int mid = start + (end - start) / 2;
 if (nums[mid] >= target) end = mid;
 else start = mid + 1;
 }
 if (start == nums.size()) return -1;
 return nums[start] == target ? start : -1;
 
 }
 
 int searchRange_right_bound(vector<int>& nums, int target) {
 if (nums.size() == 0) return -1;
 int start = 0, end = nums.size();
 
 while (start < end) {
 int mid = start + (end - start) / 2;
 if (nums[mid] <= target) {
 start = mid + 1;
 } else {
 end = mid;
 }
 }
 if (end == 0) return -1;
 return nums[end-1] == target ? (end-1) : -1;
 
 }
 
 | 
在翻转的排序数组查找目标值
leecode100-33:假设按照升序排序的数组在预先未知的某个点上进行了旋转。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | int search(vector<int>& nums, int target){if(nums.size() <= 0) return -1;
 int start = 0;
 int end = nums.size() - 1;
 while(start <= end){
 int mid = start + (end-start)/2;
 
 if(nums[mid] == target) return mid;
 
 
 if (nums[start] <= nums[mid]){
 if(nums[start] <= target && nums[mid] > target) end = mid;
 else start = mid+1;
 }
 else{
 
 if(nums[mid] < target && target< nums[start]) start = mid+1;
 else    end = mid;
 }
 }
 return -1;
 }
 
 | 
SwordToOffer 二维数组的查找
书P47,每次选取数组的右上角元素,如果目标值较小,就逐渐往左下走。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | bool find_num(int* matrix, int rows, int columns, int number){
 bool found = false;
 if (matrix != nullptr && rows>0 && columns>0) {
 int row = 0;
 int col = columns - 1;
 while (row < rows && col >=0) {
 if (matrix[row * columns + col] == number) {
 found = true;
 break;
 }
 else if (matrix[row * columns + col] > number) --col;
 else ++row;
 }
 }
 return found;
 }
 
 | 
查找第一个不小于目标值数的位置
找第一个大于等于目标值的下标,如 {1,2,3,4,4,4,5,8} target=6, 则答案是数组里8的下标7。如果是4的话,答案是3。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | long int big_binarysearch(vector<int>& nums, int target){
 if(nums.size() <= 0) return -1;
 long int start = 0;
 long int end = nums.size() - 1;
 if(nums[start] > target) return 0;
 if(nums[end] < target) return -1;
 long int res = 0;
 while(start+1 < end){
 long int mid = start + (end-start)/2;
 if (nums[mid] >= target){
 end = mid;
 res = mid;
 }
 else{
 start = mid;
 }
 }
 res = nums[start] >= target? start:end;
 return res;
 }
 
 |