在一个有序的数组中,用二分查找来寻找目标元素。时间复杂度O(logn)
1、普通版二分查找
不考虑重复元素的情况
int binarySearch(vector<int>& data, int target) {
int left = 0, right = data.size() - 1;//注意“-1”
while (left <= right) {//注意“<=”
int mid = left + (right - left) / 2;//注意防止“溢出”
if (data[mid] < target)
mid = left + 1;
else if (data[mid] > target)
mid = right - 1;
else
return mid;
}
return -1;
}
2、推广-有重复元素
2.1 元素第一次出现的位置
int binarySearch(vector<int>& data, int target) {
int left = 0, right = data.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (data[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
if(left<data.size()&&data[left]==target)
return left;
return -1;
}
测试用例:
{1, 1, 2, 3, 4},1) //0
{1, 2, 3, 4, 4}, 4) //3
{1, 2, 3, 3, 4}, 3) //2
{1, 2, 3, 4, 4}, 0) //-1
{1, 2, 3, 4, 4}, 5) //-1
{1, 1, 1, 1, 1}, 1) //0
2.2 元素最后一次出现的位置
int binarySearch(vector<int>& data, int target) {
int left = 0, right = data.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (data[mid] <= target)
left = mid + 1;
else
right = mid - 1;
}
if (right >= 0 && data[right] == target)
return right;
return -1;
}
测试用例:
{1, 1, 2, 3, 4},1) //1
{1, 2, 3, 4, 4}, 4) //4
{1, 2, 3, 3, 4}, 3) //3
{1, 2, 3, 4, 4}, 0) //-1
{1, 2, 3, 4, 4}, 5) //-1
{1, 1, 1, 1, 1}, 1) //4
2.3第一个大于等于目标值
int binarySearch(vector<int>& data, int target) {
int left = 0, right = data.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (data[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return left;
}
3.4最后一个小于等于目标值
int binarySearch(vector<int>& data, int target) {
int left = 0, right = data.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (data[mid] <= target)
left = mid + 1;
else
right = mid - 1;
}
return right;
}
STL
low_bounder
Returns an iterator pointing to the first element in the range [first,last) which does not compare less than val.
第一个大于等于val的位置
upper_bounder
Returns an iterator pointing to the first element in the range [first,last) which compares greater than val.
第一个大于val的位置