对分查找算法的应用与扩展(附代码实现与具体案例)

        二分查找,也称为折半查找,是一种常用的查找算法,用于在有序数据集中查找特定元素的位置。二分查找的时间复杂度为 O(log n),其中 n 是数据集的大小。它的优势在于对于大型有序数据集的查找效率非常高,但要求数据集必须是有序的。

       因为题目与现实中很少有完全符合对分的模式,如何利用对分查找的来变形,扩展显得十分重要。先看两个例题:

一. 给定一个长度为 n 的非降序数组和一个非负数整数 k ,要求统计 k 在数组中出现的次数
数据范围: 0≤n≤1000 , 0≤k≤100 ,数组中每个元素的值满足 0≤val≤100

代码的主要逻辑如下:

在正常对分查找以外,由于是非降序数组且循环退出的条件是left<=right,所以无论是否找到目标,退出时都有left=right+1。所以在第一个循环中,找到了依旧要执行left=mid+1,因此left一直往右靠,直到边界,我们也就找到相同数的右端。在第二个循环中找到了依旧要执行right=mid-1,因此right一直往右靠

这段代码的思路是通过两次二分查找来确定 k 在数组中的左右边界,从而计算出其出现的次数。同时,你在观察这段代码时,你会发现左右两端的边界是由nums[mid]>k以及nums[mid]>=k决定的,我们可以用这种美妙的方式来判断目标数在非降序或非升序的数列中查找。

二. 给定一个长度为n的数组 nums ,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。

1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于
2.假设 nums[-1] = nums[n] = 负无穷小
3.对于所有有效的 i 都有 nums[i] != nums[i + 1]

解析:中间比右边大,认为从右往左半边递增,则把 right 不断向左靠拢 right=mid ,注意不能是 mid-1 ,因为这个位置有可能就是峰值点。
直到遇到中间比右边小了,意味着数据开始递降了,则 left 向右偏移, left=mid+1 ; 而一旦 mid+1 位置大于了right ,意味着刚好这个 mid+1 位置,是一个左半边-右往左递降,右半边-右往左递增的点,就是一个峰值点。注意这边不能用left+(right-left+1)/2来表示mid,因此

与这道题思路相似的,还有用C语言找旋转数组最小值-CSDN博客这一题,这两道题本质上都是利用数据局部有序来帮助缩小查找的范围。因此在设计对分查找时,我们要关注这几个点:

1,循环退出的条件

2,循环推进的条件:mid,left,right初值是什么,分别怎么变化

3, 比较的条件:是mid与自己比,还是边界比,还是与目标数比

总体而言,我们要重点关注 if 里条件,通常与题目的要求有关(目标数,递增减);以及left,right的变化来缩小范围(关注是否会覆盖目标)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值