二分查找

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}; }

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


__EOF__

本文作者krystal
本文链接https://www.cnblogs.com/starkzz/p/18631286.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   krysatl  阅读(945)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示