leetcode每日一题:酿造药水需要的最少总时间
引言
今天的每日一题原题是2255. 统计是给定字符串前缀的字符串数目,直接模拟,逐个匹配words中的字符串是否是s的前缀即可。更换成前几天遇到的更有意思的一题来写这个每日一题。
题目
给你两个长度分别为 n
和 m
的整数数组 skill
和 mana
。
在一个实验室里,有 n
个巫师,他们必须按顺序酿造 m
个药水。每个药水的法力值为 mana[j]
,并且每个药水 必须 依次通过 所有 巫师处理,才能完成酿造。第 i
个巫师在第 j
个药水上处理需要的时间为 timeij = skill[i] * mana[j]
。
由于酿造过程非常精细,药水在当前巫师完成工作后 必须 立即传递给下一个巫师并开始处理。这意味着时间必须保持 同步,确保每个巫师在药水到达时 马上 开始工作。
返回酿造所有药水所需的 最短 总时间。
示例 1:
输入: skill = [1,5,2,4], mana = [5,1,4,2]
输出: 110
解释:
药水编号 | 开始时间 | 巫师 0 完成时间 | 巫师 1 完成时间 | 巫师 2 完成时间 | 巫师 3 完成时间 |
---|---|---|---|---|---|
0 | 0 | 5 | 30 | 40 | 60 |
1 | 52 | 53 | 58 | 60 | 64 |
2 | 54 | 58 | 78 | 86 | 102 |
3 | 86 | 88 | 98 | 102 | 110 |
举个例子,为什么巫师 0 不能在时间 t = 52
前开始处理第 1 个药水,假设巫师们在时间 t = 50
开始准备第 1 个药水。时间 t = 58
时,巫师 2 已经完成了第 1 个药水的处理,但巫师 3 直到时间 t = 60
仍在处理第 0 个药水,无法马上开始处理第 1个药水。
示例 2:
输入: skill = [1,1,1], mana = [1,1,1]
输出: 5
解释:
- 第 0 个药水的准备从时间
t = 0
开始,并在时间t = 3
完成。 - 第 1 个药水的准备从时间
t = 1
开始,并在时间t = 4
完成。 - 第 2 个药水的准备从时间
t = 2
开始,并在时间t = 5
完成。
示例 3:
输入: skill = [1,2,3,4], mana = [1,2]
输出: 21
提示:
n == skill.length
m == mana.length
1 <= n, m <= 5000
1 <= mana[i], skill[i] <= 5000
思路
首先要读懂题目,有个关键点是,对于同一瓶药水,在前一个巫师处理完成后,立即传递给下一个巫师进行处理。所以,这里跟直觉的贪心有一些区别,对于同一个巫师,处理一瓶药水后,并不能马上去处理下一瓶药水,要确保自己处理完成后,后一个巫师是空闲的状态。
读懂了这个点,我们来看第i瓶药水的处理,假设我们记第i瓶药水是从第beginDelay
的时刻开始处理,而每个巫师处理上一瓶(第i-1
瓶)药水的完成时间为end[],我们来看看这个beginDelay
需要满足哪些条件:
- 对于第0个巫师,自己的开始处理时间是
beginDelay
,必须晚于等于上一瓶结束时间,保证开始处理第i瓶是,自己是空闲的,即满足beginDelay >= end[0]
; - 对于第1个巫师,自己的开始处理时间是
beginDelay + skill[i] * mana[0]
,必须晚于等于上一瓶结束时间,即满足beginDelay + skill[i] * mana[0] >= end[1]
; - 对于第2个巫师,自己的开始处理时间是
beginDelay + skill[i] * (mana[0] + mana[1])
,必须晚于等于上一瓶结束时间,即满足beginDelay + skill[i] * (mana[0] + mana[1]) >= end[1]
; - 后面的巫师可以以此类推
这样,如果我们有n个巫师,对于第i瓶药水,就会有n个不等式,贪心的,求出满足这n个不等式的最小beginDelay
,就可以求出对于第i瓶药水每个巫师的最早完成时间,用于列出第i+1瓶要求的不等式。特别的,对于第0瓶药水,当前每个巫师都是空闲的,可以认为end[]
数组的值都是0。
另外,不等式中,我们对每瓶要求都会去求出mana[0]
、mana[0] + mana[1]
、mana[0] + mana[1] + mana[2]
这样的值,可以事先求一次前缀和,避免重复计算。
图解
代码
public long minTime(int[] skill, int[] mana) {
int n = skill.length;
int[] skillPreSum = new int[n + 1];
for (int i = 0; i < n; i++) {
skillPreSum[i + 1] = skillPreSum[i] + skill[i];
}
long[] end = new long[n];
for (int i = 0; i < mana.length; i++) {
long beginDelay = 0;
for (int j = 0; j < n; j++) {
beginDelay = Long.max(beginDelay, end[j] - (long)mana[i] * skillPreSum[j]);
}
for (int j = 0; j < n; j++) {
end[j] = beginDelay + (long)mana[i] * skillPreSum[j+1];
}
}
return end[n - 1];
}
耗时
leetcode每日一题:酿造药水需要的最少总时间的更多相关文章
- 【js】Leetcode每日一题-制作m束花所需的最少天数
[js]Leetcode每日一题-制作m束花所需的最少天数 [题目描述] 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k ...
- 【JavaScript】Leetcode每日一题-在D天内送包裹的能力
[JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...
- 【js】Leetcode每日一题-完成所有工作的最短时间
[js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...
- 【js】Leetcode每日一题-数组异或操作
[js]Leetcode每日一题-数组异或操作 [题目描述] 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == ...
- 【js】Leetcode每日一题-解码异或后数组
[js]Leetcode每日一题-解码异或后数组 [题目描述] 未知 整数数组 arr 由 n 个非负整数组成. 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encode ...
- 【JavaScript】Leetcode每日一题-青蛙过河
[JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...
- 【JavaScript】Leetcode每日一题-平方数之和
[JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...
- 【JavaScript】Leetcode每日一题-二叉搜索树的范围和
[JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...
- 【JavaScript】Leetcode每日一题-递增顺序搜索树
[JavaScript]Leetcode每日一题-递增顺序搜索树 [题目描述] 给你一棵二叉搜索树,请你 按中序遍历 将其重新排列为一棵递增顺序搜索树,使树中最左边的节点成为树的根节点,并且每个节点没 ...
- 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素
[python]Leetcode每日一题-寻找旋转排序数组中的最小元素 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...
随机推荐
- c#利用异步方法去模拟多线程处理业务
一个巧妙的设计 原理:利用async 标识方法执行异步处理 List<long> listIds = new List<long>();//业务任务:假设处理这个列表的任务 o ...
- 直播预览层添加滤镜效果(CIFilter使用场景)
直播预览层添加滤镜效果 原理,在显示之前,提前对图片进行滤镜处理,把处理后的图片展示出来就好了. CIFiter(滤镜类):给图片添加特殊效果(模糊,高亮等等). CIFiter滤镜分类(一个滤镜可能 ...
- C#遍历获取文件夹下所有文件
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using ...
- python的typing模块
python的typing模块 参考:3个提高 Python 开发效率的小工具.Python3 Typing模块详解 typeing模块在python中提供类型支持,主要功能有: 类型检查,防止运行时 ...
- DAB实现中用到的主要设计模式
DAB C++ 版本设计模式应用实践 1. 命令模式 (Command Pattern) 设计目标 模块解耦:实现各模块独立编译.测试.运行,消除模块间直接依赖 扩展准备:为桥接模式实现奠定基础 依赖 ...
- AI 如何重塑劳动力市场:基于 Claude 数据的深度分析
前言 本文翻译自 Anthropic 今天发布的 The Anthropic Economic Index ,经济指数报告,这份报告基于 Claude 的数据对目前的 AI 使用情况做了汇总. 引言 ...
- 每次下载idea都必装的十个插件!
IDEA必备插件 Alibaba Java Coding Guidelines 功能: 阿里巴巴Java开发规范插件,用于代码规范检查. 特点: 基于阿里巴巴Java开发手册,提供实时代码规范检查,帮 ...
- 越“挖”越有料,天翼云“息壤”助攻DeepSeek变身万能搭子!
还在为DeepSeek服务器繁忙而抓狂? 还在为API调用费用涨价而头疼? 还在为数据安全而担忧? 别急! 天翼云"息壤"算力互联调度平台出马 全面解锁DeepSeek新玩法 带你 ...
- 深入解析NoSQL数据库:从文档存储到图数据库的全场景实践
title: 深入解析NoSQL数据库:从文档存储到图数据库的全场景实践 date: 2025/2/19 updated: 2025/2/19 author: cmdragon excerpt: 通过 ...
- [WC2018] 通道 题解
三棵树就很毒瘤了,我们一棵一棵看. 关于第一棵树的路径,经典解法就是点分治和边分治,考虑哪种更加简单. 设 \(dis1/2/3(x)\) 表示 \(x\) 在第 \(1/2/3\) 棵树中的深度(第 ...