二分法

二分法体现了一种“分治”的思想。

二分查找#

当需要在一个数组中查找某个元素的时候,我们自然而然地想到遍历整个数组,找到想要的元素就停止查找。这种方法的时间复杂度是O(n),那么有没有一种更高效一点的方法呢?这时候就轮到二分查找登场了,二分查找的时间复杂度是O(logn),显然是更高效的做法。不过使用二分查找需要有一个前提:数组必须是有序的。因为二分查找是通过比较来进行提速的,如果数组是乱序,或者元素无法进行比较,显然二分查找也就失效了。

int find(vector<int>& nums, int begin, int end, int target)
{
    if(begin > end) {
        return -1;
    }
    int mid = (end - begin) / 2 + begin;
    if(target == nums[mid]) {
        return mid;
    }
    return target < nums[mid] ? find(nums, begin, mid - 1, target) :
        find(nums, mid + 1, end, target);
}

上面代码是一种二分查找的递归实现,begin表示要查找的开始位置,end表示要查找的最后位置,如果begin大于end,显然整个元素就不在数组中,返回-1表示没有找到。
计算中间位置,如果中间位置的元素正好等于要查找的元素,就返回这个位置,否则的话,比较一下目标元素是比中间位置的元素大了还是小了,小了的话,说明在前半段中,否则相反。

总结:对于有序数组来说,二分查找是一种比较好的算法。

二分插入#

leetcode上有一道简单难度的题,找到目标值,返回索引,如果不存在,则返回插入位置,要求时间复杂度在O(logn)。很明显是让使用二分法来做。

int insert(vector<int>& nums, int begin, int end, int target)
{
    if(begin == end) {
        return begin;
    }
    int mid = (end - begin) / 2 + begin;
    if(target == nums[mid]) {
        return mid;
    }
    return target < nums[mid] ? insert(nums, begin, mid, target) :
        insert(nums, mid + 1, end, target);
}

只需要把找不到的情况返回值从-1改成当前的下标即可。(end取闭区间还是开区间只会影响找不到时的判断条件,闭区间的话就是begin > end,开区间的话就是begin == end,STL中的做法都是取开区间,所以推荐和标准库保持一致,这样哪怕以后和库有交互也不至于头疼)。

作者:cwtxx

出处:https://www.cnblogs.com/cwtxx/p/18718193

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   cwtxx  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示