1.寻找第一个等于目标值的元素的位置:
1.1左闭右闭
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
if (nums[middle] > target) {
right = middle - 1; // target 在左区间,所以[left, middle - 1]
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,所以[middle + 1, right]
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
1.2左闭右开
// 版本二
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
int middle = left + ((right - left) >> 1);
if (nums[middle] > target) {
right = middle; // target 在左区间,在[left, middle)中
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,在[middle + 1, right)中
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
2.寻找第一个大于目标值的元素的位置
非递减数组中:
2.1左闭右开
//左闭右开
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
int left = 0, right = letters.size();
while(left < right){
int mid = left + (right - left) / 2;
if(letters[mid] > target)
right = mid;
else
left = mid + 1;
}
if (left == letters.size())
return letters[0];
return letters[left];
}
};
2.2左闭右闭
//左闭右闭
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
int left = 0, right = letters.size() - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(letters[mid] > target)
right = mid - 1 ;
else
left = mid + 1;
}
if (left == letters.size())
return letters[0];
return letters[left];
}
};
注: 寻找大于的话则将大于分为一类,小于等于分为一类
3.寻找第一个大于等于目标值的元素的位置
非递减数组中:
3.1左闭右开
int binarySearch(vector<int>nums, int target){
int left = 0, right = nums.size();
while(left < right){
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1;
else
right = mid;
}
return left;
}
3.2左闭右闭
int binarySearch(vector<int>nums, int target){
int left = 0, right = nums.size() - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return left;
}
注: 寻找小于的话则将小于分为一类,大于等于分为一类
4.寻找最后一个小于目标值的元素的位置
4.1左闭右闭
int binarySearchOne(vector<int>nums, int target) {
int left = 0, right = nums.size()-1;
while(left <= right) {
int mid = left + (right - left)/2;
if(nums[mid] >= target)
right = mid - 1;
else
left = mid + 1;
}
return right;
}
5.寻找最后一个小于等于目标值的元素的位置
5.1左闭右闭
int binarySearchOne(vector<int>nums, int target) {
int left = 0, right = nums.size()-1;
while(left <= right) {
int mid = left + (right - left)/2;
if(nums[mid] > target)
right = mid - 1;
else
left = mid + 1;
}
return right;
}
例如:数组 nums = {0,1,2,2,2,5,6}。这个是二分测试案例,返回索引位置
1: target = 5,return 5(下标值)
2 : target = 2, return 5(下标值)
3 : target = 2, return 2(下标值)
4 :target = 2, return 1(下标值)
5 : target = 2, return 4(下标值)