【JAVA】【刷题子】875. 爱吃香蕉的珂珂

194 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

愿高三学子们都高考顺利,金榜题名,旗开得胜,考上理想大学!

一、题目与题目分析

题目

  珂珂喜欢吃香蕉。这里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 h 小时后回来。
  珂珂可以决定她吃香蕉的速度 k(单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 k 根。如果这堆香蕉少于 k 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。  
  珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。
  返回她可以在 h 小时内吃掉所有香蕉的最小速度 kk 为整数)。
image.png
  (题目来源:力扣:875. 爱吃香蕉的珂珂)

题目分析

  首先,珂珂吃香蕉,有规定时间;在规定时间内,每堆香蕉都要吃完,求最慢的速度吃完所有香蕉。(即如何把规定时间全部用光~ 同时,还要考虑最慢速度。)
  示例1的意思是:有四堆香蕉,分别对应有3根、6根、7根、11根;规定时间8小时。就要算出8小时里,所有香蕉被吃掉的最小速度。

二、整体逻辑与主要代码

  题目分析已经比较清楚了,接下来我们进入代码设计。

整体逻辑

  珂珂的吃香蕉速度是在[1,最大堆](就是范围在1到香蕉数量最多的最大堆之间)。
  因此,在示例1中,珂珂的吃香蕉速度是在[1,11]之间,用二分法去遍历吃蕉速度,计算出所花费的时间,通过花费的时间去作比较,最终得出最合适的吃蕉速度。即为答案了~

主要代码

  整体逻辑清晰了之后,同时也有较清楚的注释。直接来看代码吧! (如有不懂的或者更好的建议,欢迎评论区分享友友的看法哈~)

class Solution {
    public int minEatingSpeed(int[] piles, int h) {
		int max = 0; // 定义最大堆的香蕉
		int left = 0; // 定义左边
		int right = piles.length - 1; // 定义右边
		while (right >= left) { // 二分查找最大值(最大堆的香蕉)
			if (piles[left] > max) {
				max = piles[left];
			}
			if (piles[right] > max) {
				max = piles[right];
			}
			left++;
			right--;
		}
		// 在[1,max]范围内,吃香蕉的最小速度 k
		left = 1; // 从1开始
		while (max >= left) {
			int countTime = 0; // 统计所吃香蕉花费的时间(需要向上取整)
			// 中间开始找
			int kMid = left + (max - left) / 2; // 该做法,防止 max + left溢出,超出整数类型范围
			for (int pile : piles) { // 求k对应的时间
				// 保证向上取整(例:pile为3时,average就为2;5对应的是3...)
				countTime += (pile - 1) / kMid + 1;
			}
			if (countTime > h) { // 左边耗时比h久,要吃快点,吃速度+1
				left = kMid + 1;
			} else {
				max = kMid - 1; // 耗时小于等于h,吃速度降低,-1
			}
		}
		// 返回左边界
		return left;
    }
}

三、结果展示

image.png

四、总结

每日都看到 朝阳冬泳怪鸽 更新冬泳视频,很喜欢他的一句话:坚持就是胜利,兄弟们,奥利给!

题目数据库

Gitee:传送门

文章小尾巴

文章写作、模板、文章小尾巴可参考:《写作“小心思”》
  感谢你看到最后,最后再说两点~
  ①如果你持有不同的看法,欢迎你在文章下方进行留言、评论。
  ②如果对你有帮助,或者你认可的话,欢迎给个小点赞,支持一下~
  我是南方者,一个热爱计算机更热爱祖国的南方人。

  (文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。)