二分查找
int search1(vector<int> arr, int target) {
if (arr.size() < 0||arr.empty() ) {
return -1;
}
int left = 0;
int right = arr.size() - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
while (arr[mid] == target && mid > 0) {
mid--;
}
if (mid == 0 && arr[mid] == target) {
return 0;
}
//加一是为了找到原来的下标
return mid+1;
}
if (arr[mid] > target) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
}
递归二分查找
int search(vector<int> arr, int target,int left,int right) {
if (left > right) {
return -1;
}
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
//当有重复元素时往左边找
if (mid>0&&arr[mid - 1] == target) {
return search(arr, target, mid-1, mid - 1);
}
return mid;
}else if(arr[mid]>target){
return search(arr, target, left, mid - 1);
}
else {
return search(arr, target, mid + 1, right);
}
}
总结
二分查找重复元素的实现思路是先使用二分查找找到目标元素的一个索引,然后向左和向右遍历数组,找到所有与目标元素相等的元素的索引。我这里考虑到了出现重复元素的情况,当找到当前值之后继续往左边找有没有重复的元素,当有重复元素时就mid就一直减,返回mid+1,是考虑到最后一个重复的元素也会使mid--,要找到原来的就必需加1。
递归二分查找因为我一直调用函数没有使用while循环去找重复的元素,当找到target时就一直调用递归去减少mid的值,当mid-1不等于要找的值时,mid就不会减1了,就会返回mid,返回的mid就是要找的最左边的值。