目录
1、704. 二分查找
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;
}
};
思路:
首先,定义了两个变量left
和right
,分别表示数组的左边界和右边界。初始时,left
被设置为数组的第一个元素的索引(0),right
被设置为数组的最后一个元素的索引(nums.size() - 1
)。
然后,使用一个循环来执行二分查找。循环条件是left
小于等于right
,这表示还存在未查找的区间。在二分查找算法中,使用left <= right
作为循环条件是为了处理以下两种情况:
-
当查找区间只剩下一个元素时,即
left
和right
指向同一个位置时,仍然需要进行一次比较。如果使用left < right
作为循环条件,那么在这种情况下循环会提前结束,导致无法正确判断目标值是否存在。 -
当查找区间为空时,即
left
大于right
时,循环条件为假,可以直接退出循环。这种情况下,表示目标值不存在于数组中。
在每次循环中,首先计算中间元素的索引mid
,通过将左边界和右边界与左边界之差相加除以2得到。这样可以将查找区间缩小一半,并且不会超出整形范围。
接下来,通过比较中间元素nums[mid]
和目标值target
的大小关系,来确定下一步的查找方向。
- 如果
nums[mid]
小于target
,说明目标值在右半部分,将left
更新为mid + 1
,缩小查找区间为右半部分。 - 如果
nums[mid]
大于target
,说明目标值在左半部分,将right
更新为mid - 1
,缩小查找区间为左半部分。 - 如果
nums[mid]
等于target
,说明找到了目标值,直接返回mid
作为结果。
如果循环结束时仍然没有找到目标值,即left
大于right
,则返回-1表示未找到。
2、34. 在排序数组中查找元素的第一个和最后一个位置
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if (nums.size() == 0)
return {-1, -1};
int left = 0, right = nums.size() - 1;
int begin = 0;
// 使用二分查找找到目标值的最左边界
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1;