LeetCode、875. 爱吃香蕉的珂珂【中等,最小速度二分】

前言

博主介绍:✌目前全网粉丝2W+,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。

涵盖技术内容:Java后端、算法、分布式微服务、中间件、前端、运维、ROS等。

博主所有博客文件目录索引:博客目录索引(持续更新)

视频平台:b站-Coder长路


LeetCode、875. 爱吃香蕉的珂珂【中等,最小速度二分】

来源:LeetCode专题《LeetCode 75》

题目及分类

题目链接:LeetCode、875. 爱吃香蕉的珂珂

类型:基础算法/二分


思路分析及代码实现

思路:

本题说让我们找到一个最少的每小时吃的香蕉数可以正好在有限时间内吃完,可以看到给我们的用例中数据量特别大,我们不可能将所有的每小时速度都去尝试模拟跑一遍,那么绝对会超时,我们选择好相应的左、右边界,然后来进行尝试二分处理。

image-20240122104702802

代码:

复杂度分析:时间复杂度O(n);空间复杂度O(1)

class Solution {
   

    //对吃的最小速度进行二分
    //1000个位置 每个位置上限为亿
    public int minEatingSpeed(int[] piles, int h) {
   
        int l = 1, r = 1000000010;
        while (l < r) {
   
            int mid = (l + r) / 2;
            if (check(mid, piles, h)) r = mid;
            else l = mid + 1;
        }
        return l;
    }

    //check可以吃完,可以吃完返回true
    public boolean check (int k, int[] piles, int h) {
   
        int hh = 0;
        for (int i = 0; i < piles.length; i ++) {
   
            int curPile = piles[i];
            if (k >= curPile) hh ++;
            else hh += (int)Math.ceil(1.0 * curPile / k); //对于curPile / k可能会得到double类型,那么我们这里就需要提前*1.0让其变成浮点数
            if (hh > h) return false;
        }
        // if (k == 3) System.out.println(hh);
        return h >= hh ? true : false;
    }
}

image-20240122104943865

代码优化

尝试优化,缩小左右边界:

①优化1:计算总和及某个元素最大值

long sum = 0;
int max = piles[0];
for (int pile: piles) {
   
    sum += pile;
    max = Math.max(max, pile);
}
//设置边界值
int l = (int)(sum / h), r = max;

image-20240122102514114

原因:因为我们只是取所有数组中最大的那个元素,那么一旦我们数组中某个元素特别大,那么就会导致我们预想的直接失效。

②优化2:适当缩减右边界,提升效率

class Solution {
   

    //对吃的最小速度进行二分
    //1000个位置 每个位置上限为亿
    public int minEatingSpeed(int[] piles, int h) {
   
        int n = piles.length;
        long sum = 0;
        for (int pile: piles) {
   
            sum += pile;
        }
        //设置边界值  对于r尽可能相对大一些(我们将小时数尽量减小,这样就可以相对拉大速度,扩展右边界)
        int l = (int)(sum / h), r = (int)(sum / (h - n + 1) + 1);
        // System.out.printf("l=%d, r=%d\n", l, r);
        //进行二分
        while (l < r) {
   
            int mid = (l + r) / 2;
            if (check(mid, piles, h)) r = mid;
            else l = mid + 1;
        }
        return l;
    }

    //check可以吃完,可以吃完返回true
    public boolean check (int k, int[] piles, int h) {
   
        int hh = 0;
        for (int i = 0; i < piles.length; i ++) {
   
            int curPile = piles[i];
            if (k >= curPile) hh ++;
            else hh += (int)Math.ceil(1.0 * curPile / k); //对于curPile / k可能会得到double类型,那么我们这里就需要提前*1.0让其变成浮点数
            if (hh > h) return false;
        }
        // if (k == 3) System.out.println(hh);
        return h >= hh ? true : false;
    }
}

image-20240122104125850


资料获取

大家点赞、收藏、关注、评论啦~

精彩专栏推荐订阅:在下方专栏👇🏻

更多博客与资料可查看👇🏻获取联系方式👇🏻,🍅文末获取开发资源及更多资源博客获取🍅


整理者:长路 整理时间:2024.1.22

相关推荐

  1. 【栈】Leetcode 155. 栈【中等

    2024-01-24 15:30:03       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-24 15:30:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-24 15:30:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-24 15:30:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-24 15:30:03       20 阅读

热门阅读

  1. vue3中几种封装让后端传参请求方式

    2024-01-24 15:30:03       32 阅读
  2. 边缘计算:在挑战与机遇的浪潮中破浪前行

    2024-01-24 15:30:03       30 阅读
  3. 边缘计算的挑战和机遇

    2024-01-24 15:30:03       37 阅读
  4. Dart/Flutter工具模块:the_utils

    2024-01-24 15:30:03       41 阅读
  5. 《设计模式的艺术》笔记 - 备忘录模式

    2024-01-24 15:30:03       33 阅读
  6. Oracle中TO_DATE与TO_CHAR区别

    2024-01-24 15:30:03       38 阅读
  7. Oracle 数据库恢复删除的数据

    2024-01-24 15:30:03       41 阅读
  8. 软件工程测试3

    2024-01-24 15:30:03       35 阅读