算法复习之分治与贪心(5)

本文介绍了二分查找算法,包括如何找到小于等于目标值的第一个数、大于目标值的第一个数等不同情况,并分析了算法核心。通过理解二分查找的上下界问题,可以灵活解决相关问题。此外,还探讨了二分查找在单调函数和实际问题如砍木头中的应用。
摘要由CSDN通过智能技术生成

写在前面

        小伙伴们想问为什么跳过了4,因为要复习不完了!!!(留下了菜狗的泪水 |_|。。。。)

        所以就先把接下来的重头戏——二分查找先整理一下,话不多说就开始吧。


关于贪心算法

        没啥想说的,因为学过数据结构、算法设计、blablabla等相关课程的小伙伴都听说过贪心,详细的一些事情由于本人很菜肯定没别人整理的好,所幸只挑选出二分查找来一起回顾一下贪心的魅力。

问题:二分查找

题目详情

        给定一个有序数组,在其中查找满足条件的某个位置:

        (1)出现小于v的第一个数;

        (2)出现小于等于v的第一个数;

        (3)出现大于v的第一个数;

        (4)出现大于等于v的第一个数。

        (5)是否存在值等于v的数

分析

        话不多说,直接看代码。

        首先最简单的问题,判断区间中是否存在值为v的数(注意使用的区间为左闭右开区间

bool binarySearch(vector<int> data, int value) {
	int left = 0;
	int right = data.size();
	while (left < right) {
		int mid = left + (right - left) / 2;
		if (data[mid] == value) {
			return true;
		}
		else if (data[mid] < value) {
			left = mid + 1;
		}
		else{
			right = mid;
		}
	}
	return false;
}

        第二个是找到大于等于v的第一个数

int binarySearch(vector<int> data, int value) {
	int left = 0;
	int right = data.size();
	while (left < right) {
		int mid = left + (right - left) / 2;
		if (data[mid] < value) {
			left = mid + 1;
		}
		else {
			right = mid;
		}
	}
	return left;
}

        第三个是找到大于v的第一个数

int binarySearch(vector<int> data, int value) {
	int left = 0;
	int right = data.size();
	while (left < right) {
		int mid = left + (right - left) / 2;
		if (data[mid] <= value) {
			left = mid + 1;
		}
		else {
			right = mid;
		}
	}
	return left;
}

        代码其实到这里就不用再写了,细心的小伙伴们已经发现其实无论题目所要求的条件如何,代码的整体逻辑结构是完全相同的,我们来总结一下二分查找的核心部分。

算法核心

        (1)首先,要搞清楚,二分查找其实划分为两大类问题,确定上界还是确定下界。比如题目中的1、2都是上界问题,而3、4都是下界问题;

        (2)其次,维护的区间到底是什么样子的(如果你精通二分查找可以直接忽略我接下来的叨叨叨)。下界问题一般建议使用左闭右开区间,而上界问题一般建议使用左开右闭区间,按照这样维护区间有利于接下来我们可以更清楚地更新区间左右边界;

        (3)接下来就是最关键的问题,判断后更新区间边界。以下界问题举例,更新基本上都是left=mid+1; right=mid;  ,原因就是有左闭右开的区间决定的,当前mid位置的值发生判定后,如果我们需要向右更新区间,那左边界必然要取mid的下一位,但如果我们向左更新区间,根据左闭右开,右边界就需要定位在mid。

问题转化

        经过核心分析之后,相信对于算法原理肯定是完全了解了,这时我们还要思考一个问题,难道上界问题与下界问题之间没有联系么?

         如图所示,标出了上界问题与下界问题的搜索结果,可以看到所有的上界问题其实都是对应的下界问题的最终搜索位置的前一位,这样我们只需要搞懂一类问题,另外一类问题就迎刃而解了。

类似问题

        留给各位自行思考,其实二分查找不一定可以只使用在有序离散序列中,也可以使用在单调函数上

砍木头

        将n根长度相同的木头砍成至少m段,要求砍完之后每段木头的长度相等。问砍后每段木头最长有多长?(对于长度进行二分查找)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小糖豆豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值