首页 > 其他分享 >【LeetCode 875】爱吃香蕉的珂珂

【LeetCode 875】爱吃香蕉的珂珂

时间:2024-05-13 20:53:19浏览次数:22  
标签:香蕉 piles int 875 mid speed LeetCode left

题目描述

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

解题思路

  • 如果当前堆剩余香蕉数量小于每小时吃的数量, 吃完当前堆就会休息不会去吃下一堆的香蕉, 所以吃完一堆所需时间就是堆的香蕉数量除以速度的向上取整值:\(\lceil {piles[i]/speed} \rceil\);
  • 首先确定答案所处的范围, 速度最小值可以是1, 最大值很明显没必要超过所有堆中香蕉数量的最大值;
  • 如果假定的速度speed能在不超过指定H小时内吃完所有香蕉, 任意大于speed的速度也肯定可以在H小时内吃完, 否则就该尝试更小的speed能否在指定时间内吃完;
  • 二分判断函数逻辑就是给定speed能否在不超过H小时内吃完所有香蕉;
  • 在给定范围内不断二分尝试, 找到最小符合需求的速度即可;
  • 时间复杂度很明显就是O(nlogMAX);
  • 对于二分范围, 可以粗略定一个较大的, 对复杂度不会有多大影响, 追求极致性能的可以再细致的缩小边界, 但是务必注意不要遗漏正确的答案区域导致出错;

解题代码

  • 朴素二分法代码:

      /**
       * 典型二分查找的题目
       * 执行用时: 6 ms , 在所有 Java 提交中击败了 99.30% 的用户
       * 内存消耗: 14.75 MB , 在所有 Java 提交中击败了 14.75% 的用户
       */
      public int minEatingSpeed(int[] piles, int h) {
          int left = 1, right = 0;
          for (int p : piles) {
              right = Math.max(p, right);
          }
          int ans = left;
          while (left <= right) {
              int mid = left + ((right - left) >> 1);
              if (eatAllWithinH(piles, h, mid)) {
                  ans = mid;
                  right = mid - 1;
              }
              else {
                  left = mid + 1;
              }
          }
          return ans;
      }
    
      private boolean eatAllWithinH(int[] piles, int h, int speed) {
          int cnt = 0;
          for (int p : piles) {
              // 吃掉一堆的小时数是piles[i]/speed向上取整的值
              cnt += (p - 1) / speed + 1;
              if (cnt > h) {
                  return false;
              }
          }
          return true;
      }
    
  • 更细致的二分范围代码:

      /**
       * 对复杂度没影响, 但是能稍微优化些的二分范围值
       * 执行用时: 1 ms , 在所有 Java 提交中击败了 99.69% 的用户
       * 内存消耗: 43.99 MB , 在所有 Java 提交中击败了 64.63% 的用户
       */
      public int minEatingSpeed(int[] piles, int h) {
          long sum = 0;
          for (int p : piles) {
              sum += p;
          }
          int left = (int) ((sum - 1) / h) + 1;
          int right = (int) (sum / (h - piles.length + 1)) + 1;
          int ans = left;
          while (left <= right) {
              int mid = left + ((right - left) >> 1);
              if (eatAllWithinH(piles, h, mid)) {
                  ans = mid;
                  right = mid - 1;
              }
              else {
                  left = mid + 1;
              }
          }
          return ans;
      }
    

标签:香蕉,piles,int,875,mid,speed,LeetCode,left
From: https://www.cnblogs.com/coding-memory/p/18189982

相关文章

  • CF875F Royal Questions
    传送门\(a[i]\)和\(b[i]\)之间连一条\(w[i]\)的边,相当于把公主当作限制条件。考虑选当前这条边是否合法:1.若选了当前这条边后变成了一棵树,那即为\(x\)个点和\(x-1\)个边,可以任意舍去一个点(因为可以有王子不结婚),所以一定合法。2.若选了当前这条边后,变成了一棵基环树,即......
  • [LeetCode] 1584.连接所有点的最小费用 Kruskal And Prim 算法 Java 并查集
    Problem:1584.连接所有点的最小费用目录Kruskal算法复杂度CodePrim算法复杂度CodeKruskal算法复杂度时间复杂度:添加时间复杂度,示例:$O(mlog(m))$空间复杂度:添加空间复杂度,示例:$O(n)$CodeclassSolution{publicintminCostConnectPoints(int[][]po......
  • LeetCode 3009. Maximum Number of Intersections on the Chart
    原题链接在这里:https://leetcode.com/problems/maximum-number-of-intersections-on-the-chart/description/题目:Thereisalinechartconsistingof n pointsconnectedbylinesegments.Youaregivena 1-indexed integerarray y.The kth pointhascoordinates......
  • LeetCode 1287. Element Appearing More Than 25% In Sorted Array
    原题链接在这里:https://leetcode.com/problems/element-appearing-more-than-25-in-sorted-array/description/题目:Givenanintegerarray sorted innon-decreasingorder,thereisexactlyoneintegerinthearraythatoccursmorethan25%ofthetime,returnthat......
  • 【LeetCode 410】分割数组的最大值
    题目描述原题链接:LeetCode.410分割数组的最大值解题思路分割的是连续子数组,所以模拟分割求子数组之和可以利用前缀和计算;设前缀和数组preSume[i]含义为[0,..,i]范围元素之和,某个子数组subArray[i,j]的元素和就是preSum[j]-preSum[i];求K个子数组元素和的最大值能转换......
  • 【LeetCode 162】寻找峰值
    题目描述原题链接:LeetCode.162寻找峰值解题思路数组相邻元素不相等,峰值可能有多个,整个数组的最大值肯定是峰值之一,直接遍历数组获取最大值也能得到答案;但是写明复杂度要求O(logn)就是否定了最简单的O(n)遍历解法,需要用二分法;按照题意数组边界另一端等同于无穷小,可......
  • 669. 修剪二叉搜索树(leetcode)
    https://leetcode.cn/problems/trim-a-binary-search-tree/description/要点是区分在区间左边还是右边,在区间左边那么右子树也还有必要去查找删除,右边同理,返回的是删除后新树的根节点要注意函数要实现单层逻辑和完成闭环语义classSolution{//查找要删除的节点,进行......
  • 450. 删除二叉搜索树中的节点(leetcode)
    https://leetcode.cn/problems/delete-node-in-a-bst/要点是确定函数语义,单层递归逻辑,确定好有返回值的这种写法,分析出5种情况,递归的时候接收好递归的返回的新树的根节点即可classSolution{//函数语义(单层递归逻辑):查找要删除的节点,并且返回删除节点后新的树的......
  • [LeetCode] 最短的桥 双BFS Java
    Problem:934.最短的桥目录思路复杂度Code思路先找到第一个岛屿,根据每一个岛屿的岛屿块的位置多源查找这个块与第二个岛屿的距离,先找到的就是最少的距离同时,将已遍历过的岛屿标记为-1,避免重复入队复杂度时间复杂度:添加时间复杂度,示例:$O(n^2)$空间复杂度:添......
  • LeetCode 1186. Maximum Subarray Sum with One Deletion
    原题链接在这里:https://leetcode.com/problems/maximum-subarray-sum-with-one-deletion/description/题目:Givenanarrayofintegers,returnthemaximumsumfora non-empty subarray(contiguouselements)withatmostoneelementdeletion. Inotherwords,youwa......