二分查找法(《代码随想录》学习笔记)

一、用途

在数组中查找某一特定值的函数并获取其下标。

二、限制条件

1. 有序数组:vector[],array[]

所查找的数组中的所有元素必须按照从小到大或从大到小的顺序排列。

如果所查找的数组不是有序数组,也可使用sort()库函数将其转化为升序排列的有序数组后再进行查找。其中sort()函数位于C++的algorithm库中,其具体用法如下:

#include <iostream>
#include <algorithm>                    // 包含sort()函数
using namespace std;                    // sort()函数位于标准库中

int arr[] = {0,2,1,3,7,4,3,2,5};
int n = sizeof(arr)/sizeof(arr[0]);     // n为数组的长度
// 默认为升序排序
sort(arr, arr + n);                    
// 降序排列
sort(arr, arr + n, greater<int>());     
2. 数组中无重复元素

若存在重复元素,函数将返回其中某一个元素的地址。

三、时空复杂度

  • 时间复杂度:O(logn)
  • 空间复杂度:O(1)

四、查找区间的两种模式

// target定义在左闭右闭区间

// 35. 搜索插入位置 - 力扣(LeetCode)

class Solution {

public:

int searchInsert_one(vector<int>& nums, int target) {

    int len = nums.size();

    int left = 0;

    int right = len - 1;

    while( left <= right) {                   // 当left = right 时,有查找成功的可能,故使用 <=

           int middle = left + ((right - left)/2);

           if(nums[middle] < target)

               left = middle + 1;            // 由于middle位置取不到,故移动至middle +1提升效率

           else if(nums[middle] > target)

                  right = middle - 1;       // 同理

           else

                 return middle;

    }

    // 若target大于数组中的所有元素,则将其插入数组末尾

    return right + 1;

}

};

// target定义在左闭右开区间

// 代码随想录 (programmercarl.com)

class Solution {

public:

    int search(vector<int>& nums, int target) {

    int left = 0;

    int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)

    while (left < right) {       // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <

           int middle = left + ((right - left) >> 1);

           if (nums[middle] > target) {

               right = middle;   

// 由于右界为开,无法取到,所以将right 赋值为同样无法取到的 middle

           } else if (nums[middle] < target) {

                   left = middle + 1; // target 在右区间,在[middle + 1, right)中

           } else {                         // nums[middle] == target

return middle;                         // 数组中找到目标值,直接返回下标

}

}

// 未找到目标值

return -1;

}

};

五、其他注意事项

// int middle;
middle = left + ((right - left) >> 1);  // 防止两数相加导致大数溢出

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值