面试手撕系列:「二分法」

最近春招开始了,面试面着面着一言不合就开始手撕代码

手撕就手撕,接下来我打算写几个专题讲讲面试中手撕的常见题目 

这些都是LeetCode上有的题目 手撕无非就是 树、链表、二分、字符串这些常用的数据结构

所以接下来请关注我们的专题吧

二分法

二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。

二分法查找的思路如下:

(1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。

(2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。

(3)如果某一步数组为空,则表示找不到目标元素。

二分法查找的时间复杂度O(logn)

感觉很抽象的样子 举一个简单通俗易懂的例子

你不知道自己长得怎么样,然后去找了10个人 ,评分分别为1-10分

首先把5号拉出来,让大家看看是不是这个人和你比哪个优秀

如果你比五号选手长得帅,那么你就不用和1-4号比了,这个区间就缩短成[5-10]

如果不幸的比五号选手长得丑,那么这个区间就缩短成了[1-4]

这里介绍两个二分法的模板 主要区别在于当前数是被划分到左区间还是右区间

模板

boolcheck(int x) {/* ... */} // 检查x是否满足某种性质
// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
intbsearch_1(int l, int r){
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断mid是否满足性质
        else l = mid + 1;
    }
    return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
intbsearch_2(int l, int r){
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

二分法作为一种搜索上快速的算法,可以把复杂度从O(N)变成O(log N)

要满足二分法搜索的条件是搜索区间内满足单调性

为什么会有两个模板呢

可以看到在区分id的时候可以分为mid=(l+r)/2(l+r)/2+1 与此同时 带来了当前数字索引划分区间的不同

话不多说先来两个题目试一试水

69 X的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:
输入: 4
输出: 2

示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
     由
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值