二分查找

704. 二分查找 - 力扣(LeetCode)
34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
35. 搜索插入位置 - 力扣(LeetCode)
69. x 的平方根 - 力扣(LeetCode)

二分查找是一种在有序数组中查找特定元素的搜索算法。它通过比较数组中间元素与目标值来工作,从而将搜索范围缩小到一半。这个过程重复进行,直到找到目标值或搜索范围为空。

工作原理

  1. 初始化:设置两个指针,low指向数组的开始,high指向数组的结束。
  2. 比较中间元素:计算中间位置mid = (low + high) / 2,并比较mid位置的元素与目标值。
  3. 缩小搜索范围
    • 如果中间元素等于目标值,则返回mid
    • 如果中间元素小于目标值,则在数组的右半部分继续搜索(low = mid + 1)。
    • 如果中间元素大于目标值,则在数组的左半部分继续搜索(high = mid - 1)。
  4. 重复:重复步骤2和3,直到找到目标值或low大于high(搜索范围为空)。

注意点 :

  1. 区间问题:左右区间
  2. 注意判断条件:相同元素
//往右更新
if (nums[mid] > target ) {
	right = mid - 1;      
} else {
    left = mid + 1;
}
//往左更新
if(nums[mid] >= target){
	right = mid - 1;      
} else {
    left = mid + 1;
}
  1. 整数溢出:使用 L + (R-L) /2
  2. 算法变种:
    1. 二分查找算法有多种变种,比如找到元素的插入位置
    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};
}

链接:
[[时间复杂度]]

posted @ 2024-12-25 19:23  stephen_zuo  阅读(969)  评论(0)    收藏  举报