代码题(57)— 二分查找总结

1、第一类: 需查找和目标值完全相等的数

举例:704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty())
            return -1;
        int low = 0;
        int high = nums.size()-1; //此处是减1,下面就是 <= 
        while(low <= high)
        {
            int mid = (low+high)/2;
            if(nums[mid] == target)
                return mid;
            else if(nums[mid] > target)
                high = mid-1;
            else
                low = mid+1;
        }
        return -1;
    }
};

2、第二类: 查找第一个不小于目标值的数,可变形为查找最后一个小于目标值的数

  因为我们要查找的目标值不一定会在数组中出现,也有可能是跟目标值相等的数在数组中并不唯一,而是有多个,那么这种情况下nums[mid] == target这条判断语句就没有必要存在。比如在数组[2, 4, 5, 6, 9]中查找数字3,就会返回数字4的位置;在数组[0, 1, 1, 1, 1]中查找数字1,就会返回第一个数字1的位置。我们可以使用如下代码:

int find(vector<int> &nums, int tar)
{
    if (nums.empty())
        return -1;
    int low = 0;
    int high = nums.size()-1;
    while (low <= high)
    {
        int mid = (low + high) / 2;
        if (nums[mid] < tar)
            low = mid + 1;
        else
            high = mid - 1;
    }
    return low;
}

 

  这一类可以轻松的变形为查找最后一个小于目标值的数,怎么变呢。我们已经找到了第一个不小于目标值的数,那么再往前退一位,返回right - 1,就是最后一个小于目标值的数。

3、查找第一个大于目标值的数,可变形为查找最后一个不大于目标值的数

  这一类也比较常见,尤其是查找第一个大于目标值的数,在C++的STL也有专门的函数upper_bound,这里跟上面的那种情况的写法上很相似,只需要添加一个等号,将之前的 nums[mid] < target 变成 nums[mid] <= target,就这一个小小的变化,其实直接就改变了搜索的方向,使得在数组中有很多跟目标值相同的数字存在的情况下,返回最后一个相同的数字的下一个位置。比如在数组[2, 4, 5, 6, 9]中查找数字3,还是返回数字4的位置,这跟上面那查找方式返回的结果相同,因为数字4在此数组中既是第一个不小于目标值3的数,也是第一个大于目标值3的数,所以make sense;在数组[0, 1, 1, 1, 1]中查找数字1,就会返回坐标5,通过对比返回的坐标和数组的长度,我们就知道是否存在这样一个大于目标值的数。参见下面的代码:

int find(vector<int> &nums, int tar)
{
    if (nums.empty())
        return -1;
    int low = 0;
    int high = nums.size()-1;
    while (low <= high)
    {
        int mid = (low + high) / 2;
        if (nums[mid] <= tar)// 将这里的大于号,改为大于等于
            low = mid + 1;
        else
            high = mid - 1;
    }
    return low;
}

 

  这一类可以轻松的变形为查找最后一个不大于目标值的数,怎么变呢。我们已经找到了第一个大于目标值的数,那么再往前退一位,返回right - 1,就是最后一个不大于目标值的数。比如在数组[0, 1, 1, 1, 1]中查找数字1,就会返回最后一个数字1的位置4,这在有些情况下是需要这么做的。

 

转载于:https://www.cnblogs.com/eilearn/p/9544371.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.8是关于二分查找目。二分查找是一种常用的查找算法,用于在有序数组中快速查找指定元素的位置。引用提供了一个C语言的二分查找的实现代码。该代码使用了一个名为Position的结构体,在数组L中查找元素X的位置。 具体实现思路如下: 1. 定义两个变量min和max,分别表示数组的最小索引和最大索引。初始时,min=1,max=L->Last,其中L->Last表示数组L的最后一个元素的索引。 2. 使用一个循环语句,不断缩小查找范围,直到找到目标元素或查找范围为空。 3. 在每次循环迭代中,计算中间索引mid=(max+min)/2,将数组的中间元素与目标元素进行比较。 4. 如果目标元素小于中间元素,则更新max=mid-1,缩小查找范围为左半部分。 5. 如果目标元素大于中间元素,则更新min=mid+1,缩小查找范围为右半部分。 6. 如果目标元素等于中间元素,则说明找到了目标元素,返回mid作为目标元素的位置。 7. 如果循环结束后仍然没有找到目标元素,则返回NotFound表示未找到。 注意:该代码的输入样例是一个有序数组L和目标元素X,输出结果是目标元素X在数组L中的位置。而输入样例1和输出样例1是示例输入和输出,不是该代码的输入和输出。 希望对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [《量化投资以Python为工具》资源及源码及习](https://download.csdn.net/download/fairy_tail20/88248689)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [习1.8 二分查找 (20 分)](https://blog.csdn.net/weixin_43838785/article/details/101601296)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值