leetcode 875:爱吃香蕉的珂珂

leetcode 875:爱吃香蕉的珂珂

1.问题描述:

在这里插入图片描述


测试数据:

在这里插入图片描述


2.先验知识:

这道题是一道很经典的二分应用的题目。在介绍如何解决这道题之前,我首先抛出我平时习惯两套二分模板,只需要在return时稍做修改,便可以解决90%以上的二分问题,相当好用。下面给出的例子中默认在逻辑上是升序排序的,如果在实际应用中遇到降序问题我们只需要稍作思考修改代码即可。

#第一种:当check为true时,结果落在左侧区间,此时我们找到的是arr中第一个大于等于target的数。
def biselect_left(l,r,arr,target):
	#l 是 二分的左边界
	#r 是 二分的右边界
	while l < r:
		mid = l + r >> 1
		if check(mid) >= target:
			r = mid
		else:
			l = mid + 1
	return l
_____________________________________________________________________________________
#第二种:当check为true时,结果落在右侧区间,此时我们找到的是arr中第一个小于等于target的数。
def biselect_right(l,r,arr,target):
	#l 是 二分的左边界
	#r 是 二分的右边界
	while l < r:
		mid = l + r + 1 >> 1
		if check(mid) <= target:
			l = mid
		else:
			r = mid - 1
	return l
	

3.思路:

当我们读完了上述两个模板时,其实就可以解决大部分比较简单的二分问题了,具体问题请自行前往leetcode二分学习计划入门级别中练习。值得注意的一点是,我习惯了平时将二分区间mid写作直接除以2,但有时会因为数组太大产生越界问题,请各位在入门时养成好习惯:l + (r - l) / 2就不会产生越界了。
好了,言归正传,当我第一眼看到这道题,什么?这鬼问题能用二分解决?没错,相信和我一样刚刚入门算法的人一定会被这样的想法震撼到,我们学到的二分是什么,使用条件我可以像背课文一样背出来:有序数组~。没错,确实是有序,但是我们似乎被数学思想禁锢了,2 > 1 是有序的,它为什么是有序的,是因为我们知道在数值上2确确实实大于1,可我要问你为什么 arr[2]> arr[1],也许你会觉得我这是一个非常弱智的问题,我tm从小学就知道2 > 1,数组是升序的,当然arr[2] > arr[1]了。非常好,相信如果到这里你能懂的话,你马上就能理解这道题为什么能用二分了。上文我提到了,在逻辑上是升序的。我们是将下标对数据抽象成了一个哈希映射函数,下标对应哈希位置的值。
重点来了:
这道题我们的目标是找到一个吃香蕉的最小速度k,使得吃完香蕉的最小时间小于等于h。让我们思考一下,这里target相当于h,我们要找到一个自变量k,使得f(k) <= h,这里f代表吃完香蕉时间的函数,我们可以发现,其是单调的,所以和之前提到的哈希映射是一个道理。那么,开始无脑二分。等等等等,在二分之前,我们有两个模板啊,我们应该选择哪个模板呢?来思考一下,我们要找到一个最小的k,使得f(k) <= h,也就是我们要在时间的数轴上找到一个小于等于h的数,那当然是选择第一个了。ok,相信讲到这里,你应该能明白这道题为什么能选择二分以及具体应该怎么做了。接下来看看python的具体实现,其他语言殊途同归,我就不多赘述了。


4.具体实现:
class Solution:
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
    	def f(piles,k):
    		total_hour = 0
    		for pile in piles:
    			total_hour += pile//k
    			if pile % k != 0:
    				total_hour += 1
    		return total_hour
    	#速度相当于数据下标,f(k)相当于哈希映射
    	l = 1
    	r = 1000000100 #题目给定的h范围
    	#接下来就是套模板
    	while l < r:
    		mid = l + r >> 1
    		if f(piles,mid) <= h:
    			r = mid
    		else:
    		 	l = mid + 1
    	return l			
总结:

这道题其实如果见过这个思路的话是很容易想到的,但是如果没见过确实还是比较困难的,所以特此记录一下,另附我混在今年秋招群中看到的某厂的面试原题,请各位自品。
在这里插入图片描述
那么就到此结束了,下次作为小白的我有了更深的感悟再见,感谢各位的观看,欢迎各位来指出错误讨论。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值