leetcode刷题记录-875. 爱吃香蕉的珂珂

111 阅读1分钟

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

前言

今天的题目为中等,一道二分查找的变种题目,使用二分查找的思维能够节省时间复杂度,快速的查找到我们需要的那个值。

每日一题

今天的题目是 875. 爱吃香蕉的珂珂,难度为中等

  • 珂珂喜欢吃香蕉。这里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 h 小时后回来。

  • 珂珂可以决定她吃香蕉的速度 k (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 k 根。如果这堆香蕉少于 k 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。  

  • 珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。

  • 返回她可以在 h 小时内吃掉所有香蕉的最小速度 k(k 为整数)。

 

示例 1:

输入:piles = [3,6,7,11], h = 8
输出:4

示例 2:

输入:piles = [30,11,23,4,20], h = 5
输出:30

示例 3:

输入:piles = [30,11,23,4,20], h = 6
输出:23

 

提示:

  • 1 <= piles.length <= 104
  • piles.length <= h <= 109
  • 1 <= piles[i] <= 109

题解

二分查找

题目比较简单,能够根据题意转化为二分查找的问题。

首先我们要确定,每小时都要吃香蕉,那么每小时吃的最少的根数就是 1 ,每次最多吃一堆香蕉,那么每小时吃的最多的就是香蕉里面最多的那一堆的数量,知道这两点,那么就能够知道最开始的吃的速度的最小值和最大值,并且根据这一点,我们就能够获取当前吃的速度的中位数,用它来判断当前的中位数是快了还是慢了。

因为题目需要我们求出在 h 小时内吃掉所有香蕉的最小速度 k

设每一堆香蕉为 pile 个,那么吃掉每一堆所需要的时间就是 pile/k 向上取整,这样我们就能够求出在当前速度下吃掉所有香蕉所需要的时间,

那么我们就可以利用二分查找不断地缩小这个范围,知道最后求出这个刚好满足条件的速度 k。

function minEatingSpeed(piles: number[], h: number): number {
  let left = 1, right = Math.max(...piles)
  while (left < right) {
      const mid = (left + right) >> 1
      if (getTime(mid, piles) <= h) {
          right = mid
      } else {
          left = mid + 1
      }
  }
  return left
};

function getTime(k:number, piles: number[]):number{
  let s = 0
  for(const pile of piles) {
      s += Math.ceil(pile / k)
  }
  return s
}

image.png