力扣labuladong一刷day24天

力扣labuladong一刷day24天

文章目录

      • 力扣labuladong一刷day24天
      • [一、875. 爱吃香蕉的珂珂](#一、875. 爱吃香蕉的珂珂)
      • [二、1011. 在 D 天内送达包裹的能力](#二、1011. 在 D 天内送达包裹的能力)
      • [三、410. 分割数组的最大值](#三、410. 分割数组的最大值)

一、875. 爱吃香蕉的珂珂

题目链接:https://leetcode.cn/problems/koko-eating-bananas/?utm_source=LCUS\&utm_medium=ip_redirect\&utm_campaign=transfer2china

思路:本质上是一个二分搜索左边界的问题,每个小时吃多少都可以,要找的是每小时吃k个,h个小时正好吃完,抽取出来计算用多少小时吃完的函数,小时数超了应该扩大k,小时数少了应该缩小k。

java 复制代码
class Solution {
   public int minEatingSpeed(int[] piles, int h) {
        int left = 1, right = 1000000000;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (f(mid, piles) <= h) {
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        return left;
    }

    long f(int k, int[] piles) {
        long h = 0;
        for (int i = 0; i < piles.length; i++) {
            h += piles[i] / k;
            if (piles[i] % k > 0) {
                h++;
            }
        }
        return h;
    }
}

二、1011. 在 D 天内送达包裹的能力

题目链接:https://leetcode.cn/problems/capacity-to-ship-packages-within-d-days/

思路:这题类似上一题,有 一个容量K,要求在day天运送完成所使用的最小k。在left和right的选取上要先设置好范围,最小就是最小的包裹,最大就是全体都能放下。计算天数时注意结尾的处理,最后没装满或者装多了只要不是正好是0都要多加1天。

java 复制代码
class Solution {
      public int shipWithinDays(int[] weights, int days) {
        int left = 0;
        int right = 1;
        for (int w : weights) {
            left = Math.max(left, w);
            right += w;
        }
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (f(weights, mid) <= days) {
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        return left;
    }

    int f(int[] weights, int x) {
        int day = 0, sum = 0;
        for (int i = 0; i < weights.length; i++) {
            if (sum+weights[i] == x) {
                day++;
                sum = 0;
            }else if (sum + weights[i] < x) {
                sum += weights[i];
            }else {
                day++;
                sum = weights[i];
            }
        }
        return sum == 0 ? day : day+1;
    }
}

三、410. 分割数组的最大值

题目链接:https://leetcode.cn/problems/split-array-largest-sum/

思路:把数组顺序分成k个区间,要求所有的分法当中各个和最大区间的 最小值。其实也就是有很多货物,让k天运完,求船的最小容量,

一样是先确定left和right的边界,边界里的数是船的容量,不可能说船的容量装不下某一个货物,故left应该是所有货物中的最大值。right的话看天数要求,天数最少1天,right最大为货物总和。

f(mid) 与 k如何调节,其实直接分析就行,怎么写都可以,加入写成f(mid) <= k 那么说明船容量太大,导致天数少了,所以缩小容量天数就大了,即right = mid -1;

else就是 f(mid) > k 那么就是船的容量太小,导致天数多了,故扩大容量让天数变下,left = mid + 1;

java 复制代码
class Solution {
    public int splitArray(int[] nums, int k) {
        int left = 0, right = 0;
        for (int i : nums) {
            left = Math.max(left, i);
            right += i;
        }
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (f(nums, mid) <= k) {
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        return left;
    }

    int f(int[] nums, int c) {
        int m = 0, sum = 0;
        for (int i = 0; i < nums.length; i++) {
            if (sum + nums[i] == c) {
                m++;
                sum = 0;
            } else if (sum + nums[i] < c) {
                sum += nums[i];
            }else {
                m++;
                sum = nums[i];
            }
        }
        return sum == 0 ? m : m + 1;
    }
}
相关推荐
江畔柳前堤4 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore5 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考6 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX7 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面8 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号8 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽8 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI8 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者10 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者10 小时前
【征程6】校准量化中HistogramObserver解析
算法