二分查找(C++实现)

学习视频:acwing算法基础课

思路:目标值在[ l , r ]中,每次将区间长度缩小一半,当l==r时,我们就找到了目标值

有单调性可以二分,可以二分不一定有单调性

整数二分

二分本质:

                区间[ l , r ]中,存在某种性质,此性质半边区间满足,半边区间不满足,区间被一分为二。如果这样的性质存在,那么二分可以寻找这个性质的边界即点1和点2

情形一:寻找某性质的右边界(以上图为例,即点1

        第一步:寻找区间中间值mid=(l+r+1)/2,并判断中间值是否符合橙色区间的性质

                        mid=(l+r+1)/2中加1的原因:当l与r相邻时,如l=3,r=4,若mid=(l+r)/2=3,l向下取整仍然为3,没有改变,所以需要+1。

        第二步:如果满足条件,则mid一定在左侧橙色区间内,mid一定小于等于点1,换言之点1一定在mid右侧或者就是mid,所以更新区间方式:l=mid

                      如果不满足条件,则mid一定在右侧绿色区域内,mid一定大于点1,换言之点1一定在mid左侧,所以更新方式r=mid-1

情形二:寻找某性质的左边界(以上图为例,即点2

        第一步:寻找区间中间值mid=(l+r)/2,并判断中间值是否符合绿色区间的性质

        第二步:如果满足条件,则mid一定在右侧绿色区间内,mid一定大于等于点2,换言之点2一定在mid左侧或者就是mid,所以更新区间方式:r=mid

                      如果不满足条件,则mid一定在左侧橙色区域内,mid一定小于点2,换言之点2一定在mid右侧,所以更新方式l=mid+1

举例:给出一个数组1 2 2 3 3 3 5 9  ,找出其中3的起始和终止下标

#include<iostream>
using namespace std;

const int N = 100005;//数组最大元素个数

int n, q[N], k;//n:数组元素个数,k带查找端点下标的数字

int main()
{
	cin >> n >> k;
	for (int i = 0; i < n; i++)
	{
		cin >> q[i];
	}
	
	int l = 0, r = n - 1;
	//起始坐标
	while (l < r)
	{
		int mid = (l + r) / 2;
		if (q[mid] >= k) r = k;
		else l = mid + 1;
	}

	cout << l << " ";
	l = 0, r = n - 1;
	//终止坐标
	while (l < r)
	{
		int mid = (l + r + 1) / 2;
		if (q[mid] <= k) l = mid;
		else r = mid - 1;
	}

	cout << r;

	return 0;
}

浮点数二分

 与整数二分相似在区间l到r上找一个性质使半边区间符合,半边区间不符合,当区间长度很小时就可以认为是找出边界啦。

举个例子:找出数字3的平方根

#include<iostream>
using namespace std;

const int N = 100005;//数组最大元素个数

int n, q[N], k;//n:数组元素个数,k带查找端点下标的数字

int main()
{
	double x=3;
	double l = 0, r = x;

	while (r - l > 1e-8)//当r-l大于1的-8次方时就继续寻找
	{
		double mid = (l + r) / 2;
		if (mid * mid >= x) r = mid;//mid平方大于等于x时说明mid大于等于x的平方根所以区间调整为l到mid
		else l = mid;//mid平方小于x时说明mid小于x的平方根所以区间调整为mid到r
 	}

	cout << l;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值