二分查找
704. 二分查找 - 力扣(LeetCode)
34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
35. 搜索插入位置 - 力扣(LeetCode)
69. x 的平方根 - 力扣(LeetCode)
二分查找是一种在有序数组中查找特定元素的搜索算法。它通过比较数组中间元素与目标值来工作,从而将搜索范围缩小到一半。这个过程重复进行,直到找到目标值或搜索范围为空。
工作原理
- 初始化:设置两个指针,
low指向数组的开始,high指向数组的结束。 - 比较中间元素:计算中间位置
mid = (low + high) / 2,并比较mid位置的元素与目标值。 - 缩小搜索范围:
- 如果中间元素等于目标值,则返回
mid。 - 如果中间元素小于目标值,则在数组的右半部分继续搜索(
low = mid + 1)。 - 如果中间元素大于目标值,则在数组的左半部分继续搜索(
high = mid - 1)。
- 如果中间元素等于目标值,则返回
- 重复:重复步骤2和3,直到找到目标值或
low大于high(搜索范围为空)。
注意点 :
- 区间问题:左右区间
- 注意判断条件:相同元素
//往右更新
if (nums[mid] > target ) {
right = mid - 1;
} else {
left = mid + 1;
}
//往左更新
if(nums[mid] >= target){
right = mid - 1;
} else {
left = mid + 1;
}
- 整数溢出:使用 L + (R-L) /2
- 算法变种:
- 二分查找算法有多种变种,比如找到元素的插入位置
- 找到最后一个不大于目标值的元素等
特点
- 效率:二分查找的[[时间复杂度]]为 O(log n),其中 n 是数组中的元素数量。这使得它比线性搜索(O(n))更高效,尤其是在大型数据集中。
- 适用性:二分查找仅适用于有序数组。如果数组未排序,需要先进行排序,这会增加额外的时间复杂度。
- 实现简单:二分查找的算法逻辑简单,易于实现
二分法第一种写法
int search(vector<int>& nums, int target) {
int len = nums.size()-1;
int left = 0, right = len;
while (left <= right){
int mid = (lefg + right) / 2;
if(target > nums[mid]) left = mid + 1;
else if (target < nums[mid]) right = mid - 1;
else return mid;
}
return -1;
}
二分法第二种写法
递归二分
bool binarySearchRecursive(const vector<int>& nums, int target, int left,
int right) {
if (left > right) return -1;
int mid = (left + right) / 2;
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
return binarySearchRecursive(nums, target, mid + 1, right);
else
return binarySearchRecursive(nums, target, left, mid - 1);
}
搜索左右位置
int binarySearch(vector<int>& nums,int targer,bool flage){
int left = 0, right = nums.size()-1, ans = (int)nums.size();
while(left <= right){
int mid = left + (right-left) /2;
if(nums[mid] > targer || (flage && nums[mid] >= targer)){
right = mid -1;
ans = mid;
}
else{
left = mid + 1;
}
}
return ans;
}
vector<int> searchRange(vector<int>& nums, int target) {
int Lindex = binarySearch(nums, target, true);
int Rindex = binarySearch(nums, target , false);
if(nums[Lindex] == target && nums[Rindex]==target && Rindex< nums.size() && Lindex<=Rindex){
vector<int>{Lindex,Rindex};
}
return vector<int>{-1,-1};
}
链接:
[[时间复杂度]]

浙公网安备 33010602011771号