1--二分查找法
二分查找法用于有序数组的元素查找,一般可以分为左闭右闭 写法、左闭右开 写法、左开右闭写法,其中左闭右闭写法最常用;
cpp
#include <iostream>
#include <vector>
class Solution {
public:
// 左闭右闭写法
int search1(std::vector<int>& arr, int target){
int left = 0, right = arr.size() - 1;
while(left <= right){ // 因为是左闭右闭写法,当left == right时[left, right]也是合法的,因此left <= right
int mid = left + (right - left) / 2;
if(arr[mid] > target){
right = mid - 1;
}
else if(arr[mid] < target){
left = mid + 1;
}
else return arr[mid];
}
return -1; // 表示未找到
}
// 左闭右开写法
int search2(std::vector<int>& arr, int target){
int left = 0, right = arr.size();
while(left < right){ // 因为是左闭右开写法,当left == right时[left, right)是非法的,因此left < right
int mid = left + (right - left) / 2;
if(arr[mid] > target){
right = mid; // 右开
}
else if(arr[mid] < target){
left = mid + 1; // 左闭
}
else return arr[mid];
}
return -1; // 表示未找到
}
// 左开右闭写法
int search3(std::vector<int>& arr, int target){
int left = -1, right = arr.size() - 1;
while(left < right){ // 因为是左闭右开写法,当left == right时(left, right]是非法的,因此left < right
int mid = left + (right - left) / 2;
if(arr[mid] > target){
right = mid - 1; // 右闭
}
else if(arr[mid] < target){
left = mid; // 左开
}
else return arr[mid];
}
return -1; // 表示未找到
}
};
int main(int argc, char *argv[]){
std::vector<int> test = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int target = 2;
Solution S1;
int res1 = S1.search1(test, target);
int res2 = S1.search2(test, target);
int res3 = S1.search3(test, target);
std::cout << res1 << ", " << res2 << ", " << res3 << std::endl;
return 0;
}
2--二分查找法进阶
2-1--寻找第一个等于目标值的位置
等于号 = 放在哪个条件判断的依据:当 arr[mid] == target 时,应该往哪一边继续二分寻找;
cpp
#include <iostream>
#include <vector>
class Solution {
public:
// 左闭右闭写法
int search1(std::vector<int>& arr, int target){
int left = 0, right = arr.size() - 1;
int res = -1;
while(left <= right){
int mid = left + (right - left) / 2;
if(arr[mid] >= target){
res = mid; // 记录可能的位置
right = mid - 1;
}
else if(arr[mid] < target){
left = mid + 1;
}
}
if(res == -1 || arr[res] != target) return -1; //未找到target
return res;
}
};
int main(int argc, char *argv[]){
std::vector<int> test = {1, 2, 2, 2, 3, 3, 4};
int target = 2;
Solution S1;
int res1 = S1.search1(test, target);
std::cout << res1 << std::endl;
return 0;
}
2-2--寻找最后一个等于目标值的位置
等于号 = 放在哪个条件判断的依据:当 arr[mid] == target 时,应该往哪一边继续二分寻找;
cpp
#include <iostream>
#include <vector>
class Solution {
public:
// 左闭右闭写法
int search1(std::vector<int>& arr, int target){
int left = 0, right = arr.size() - 1;
int res = -1;
while(left <= right){
int mid = left + (right - left) / 2;
if(arr[mid] > target){
right = mid - 1;
}
else if(arr[mid] <= target){
res = mid; // 记录可能的位置
left = mid + 1;
}
}
if(res == -1 || arr[res] != target) return -1; //未找到target
return res;
}
};
int main(int argc, char *argv[]){
std::vector<int> test = {1, 2, 2, 2, 3, 3, 4};
int target = 2;
Solution S1;
int res1 = S1.search1(test, target);
std::cout << res1 << std::endl;
return 0;
}