C++ 二分法OJ

本文介绍了二分查找及其在查找元素(如首末位置、平方根)、数组排序(如山脉数组)和特定问题(如寻找峰值、旋转数组中的最小值及点名)中的应用。每个算法都涉及到二分查找的思想,优化了查找效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1、704. 二分查找 

2、34. 在排序数组中查找元素的第一个和最后一个位置

3、69. x的平方根

4、35. 搜索插入位置

5、852. 山脉数组的峰顶索引 

6、162. 寻找峰值

7、153. 寻找旋转排序数组中的最小值 

8、LCR 173. 点名 


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

思路:

首先,定义了两个变量leftright,分别表示数组的左边界和右边界。初始时,left被设置为数组的第一个元素的索引(0),right被设置为数组的最后一个元素的索引(nums.size() - 1)。

然后,使用一个循环来执行二分查找。循环条件是left小于等于right,这表示还存在未查找的区间。在二分查找算法中,使用left <= right作为循环条件是为了处理以下两种情况:

  1. 当查找区间只剩下一个元素时,即leftright指向同一个位置时,仍然需要进行一次比较。如果使用left < right作为循环条件,那么在这种情况下循环会提前结束,导致无法正确判断目标值是否存在。

  2. 当查找区间为空时,即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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Han同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值