以LeetCode上这个题为例:34. 在排序数组中查找元素的第一个和最后一个位置
参考自这个解析.
主要是方便以后自己好复习
1. 搜索一个值
int binary_search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if(nums[mid] == target) {
// 直接返回
return mid;
}
}
// 直接返回
return -1;
}
2.搜索左右边界:
#include <iostream>
#include <vector>
#include "unistd.h"
using namespace std;
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
// 开区间写法
// int l = searchLeft(nums, target);
// int r = searchRight(nums, target);
// return {l, r};
// 闭区间写法
int left = left_bound(nums, target);
int right = right_bound(nums, target);
return {left, right};
}
// 开区间写法 [left, right)
int searchLeft(vector<int>& nums, int target){
if(nums.size() == 0) return -1;
int l = 0;
int r = nums.size();
while(l < r){
int m = (l + r) >> 1;
if(nums[m] >= target){
r = m;
}
else if(nums[m] < target){
l = m + 1;
}
}
// 边界检查
// if(l == nums.size()) return -1;
return (nums[l] == target)? l : -1;
}
// 开区间写法 [left, right)
int searchRight(vector<int>& nums, int target){
if(nums.size() == 0) return -1;
int l = 0;
int r = nums.size();
while(l < r){
int m = (l + r) >> 1;
if(nums[m] <= target){
l = m + 1;
}
else if(nums[m] > target){
r = m;
}
}
// 边界检查
// if(l == 0) return -1; // 这里返回值代表比target小的数字个数
return nums[l-1] == target? l - 1 : -1;
}
// 闭区间写法 [left, right]
int left_bound(vector<int>& nums, int target){
if(nums.size() == 0) return -1;
int left = 0;
int 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 if(nums[mid] > target){
right = mid - 1;
}
}
// 边界检查
if(left >= nums.size() || nums[left] != target) return -1;
return left;
}
// 闭区间写法 [left, right]
int right_bound(vector<int>& nums, int target){
if(nums.size() == 0) return -1;
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int mid = (left + right) >> 1;
if(nums[mid] == target){
left = mid + 1;
}
else if(nums[mid] < target){
left = mid + 1;
}
else if(nums[mid] > target){
right = mid - 1;
}
}
// 边界检查 [left, right]
if(right < 0 || nums[right] != target) return -1;
return right;
}
};
int main()
{
Solution sol;
vector<int> nums = {5,7,7,8,8,10};
int target = 8;
int target1 = 0;
int target2 = 12;
vector<int> res = sol.searchRange(nums, target);
vector<int> res1 = sol.searchRange(nums, target1);
vector<int> res2 = sol.searchRange(nums, target2);
cout << res[0] << " " << res[1] << endl;
cout << res1[0] << " " << res1[1] << endl;
cout << res2[0] << " " << res2[1] << endl;
return 0;
}