二分查找算法简介及在排序数组中查找元素的首尾位置
二分查找算法原理及其在有序数组中的应用。涵盖基础二分查找寻找目标值索引,以及进阶版查找目标值首次和末次出现位置。通过左右边界收缩策略,实现 O(log n) 时间复杂度。提供 C++ 代码模板及详细逻辑分析,适用于解决排序数组中的定位问题。

二分查找算法原理及其在有序数组中的应用。涵盖基础二分查找寻找目标值索引,以及进阶版查找目标值首次和末次出现位置。通过左右边界收缩策略,实现 O(log n) 时间复杂度。提供 C++ 代码模板及详细逻辑分析,适用于解决排序数组中的定位问题。

二分查找(Binary Search),也称为折半查找,是一种高效的有序数组查找算法。其核心思想是通过不断将搜索区间减半,快速缩小目标值的可能范围,最终找到目标值或确定其不存在。该算法的时间复杂度为 O(log n),远优于顺序查找的 O(n),在处理大规模有序数据时优势显著。
题目描述: 给定一个升序排列的整数数组 nums 和一个目标值 target,找出目标值在数组中的索引。如果不存在,返回 -1。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 防止数据溢出
if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
else
return mid;
}
return -1;
}
};
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 防止数据溢出
if (条件判断) left = mid + 1;
else if (条件判断) right = mid - 1;
else return 结果;
}
题目描述: 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值,返回 [-1, -1]。
算法思路: 使用二分思想,根据数据的性质,在某种判断条件下将区间一分为二,然后舍去其中一个区间,再在另一个区间内查找。
方便叙述,用 x 表示该元素,resLeft 表示左边界,resRight 表示右边界。
寻找左边界思路: 寻找左边界时需要注意以左边界划分的两个区间的特点:
关于 mid 的落点,分为两种情况:
由此,就可以通过二分来快速寻找左边界。 注意:这里找中间元素需要向下取整。因为后续移动左右指针的时候,左指针 left = mid + 1 会向后移动,而右指针 right = mid 可能会原地踏步(例如剩下 1, 2 两个元素,left=1, right=2, mid=2。若向上取整则 mid=2,更新后 left,right,mid 不变,陷入死循环)。因此当 right = mid 时,要向下取整。
寻找右边界思路: 寻找右边界时注意到右边界的特点:
关于 mid 的落点,分为两种情况:
由此,就可以通过二分来快速寻找右边界。 注意:这里找中间元素需要向上取整。因为后续移动左右指针的时候,左指针 left = mid 可能会原地踏步(例如剩下 1, 2 两个元素,left=1, right=2, mid=1。若向下取整则 mid=1,更新后 left,right,mid 不变,陷入死循环)。因此当 left = mid 时,要向上取整。
C++ 算法代码:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int begin = 0, end = 0, mid = 0;
if (nums.empty()) {
return {-1, -1};
}
// 1. 查找区间左端点
int left = 0, right = nums.size() - 1;
while (left < right) {
mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1;
else
right = mid;
}
if (nums[left] == target)
begin = left;
else
return {-1, -1};
// 2. 查找区间右端点
left = 0, right = nums.size() - 1;
while (left < right) {
mid = left + (right - left + 1) / 2; // 向上取整
if (nums[mid] <= target)
left = mid;
else
right = mid - 1;
}
if (nums[right] == target)
end = right;
else
return {-1, -1};
return {begin, end};
}
};
本文讲解了二分查找的基础应用及变体,重点在于处理边界条件和避免死循环。掌握左右边界的收缩逻辑是解决此类问题的关键。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online