网站建设的通知,一级域名建站网站建设行吗,河南住房和城乡建设局网站,企业邮箱登录界面从0开始的秋招刷题路#xff0c;记录下所刷每道题的题解#xff0c;帮助自己回顾总结
2335. 装满杯子需要的最短总时长
现有一台饮水机#xff0c;可以制备冷水、温水和热水。每秒钟#xff0c;可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。
给你一个下标从 0 开…从0开始的秋招刷题路记录下所刷每道题的题解帮助自己回顾总结
2335. 装满杯子需要的最短总时长
现有一台饮水机可以制备冷水、温水和热水。每秒钟可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。
给你一个下标从 0 开始、长度为 3 的整数数组 amount 其中 amount[0]、amount[1] 和 amount[2] 分别表示需要装满冷水、温水和热水的杯子数量。返回装满所有杯子所需的 最少 秒数。
示例 1
输入amount [1,4,2] 输出4 解释下面给出一种方案 第 1 秒装满一杯冷水和一杯温水。 第 2 秒装满一杯温水和一杯热水。 第 3 秒装满一杯温水和一杯热水。 第 4 秒装满一杯温水。 可以证明最少需要 4 秒才能装满所有杯子。 示例 2
输入amount [5,4,4] 输出7 解释下面给出一种方案 第 1 秒装满一杯冷水和一杯热水。 第 2 秒装满一杯冷水和一杯温水。 第 3 秒装满一杯冷水和一杯温水。 第 4 秒装满一杯温水和一杯热水。 第 5 秒装满一杯冷水和一杯热水。 第 6 秒装满一杯冷水和一杯温水。 第 7 秒装满一杯热水。 示例 3
输入amount [5,0,0] 输出5 解释每秒装满一杯冷水。
提示
amount.length 3 0 amount[i] 100
贪心尽可能多的装两杯总次数就是sum(a[i]) / 2 (上取整) 如果a[0], a[1], a[2]其中某一个数另外两个那总次数就是a[i]_max 法一 数学问题
class Solution {
public:int fillCups(vectorint a) {sort(a.begin(), a.end());if (a[0] a[1] a[2]) return a[2];return (a[0] a[1] a[2] 1) / 2;}
};优化
class Solution {
public:int fillCups(vectorint a) {return max({a[0], a[1], a[2], (a[0] a[1] a[2] 1) / 2}); //注意这里要加 max( { } ) ;}
};法二堆 (本质和排序一样) 思路
把数组建成大根堆。
每一次都尽量装 2 杯不同的水 ( 每次都取出最大值t1和次大值t2 )
2.1 若!t1 直接break返回res (整个堆的元素都是 0 )
2.2 若t1 1 t2 1就装这两杯水 同时heap.insert(t1 - 1 and t2 - 1)
2.3 若t1 1 !t2 res t1然后break返回res
注意: 我们只关心剩余的杯数量而不关心具体装的是什么水所以只需要维护剩余杯数的具体数值即可不需要知道其对应的水的属性
class Solution {
public:int fillCups(vectorint amount) {// greedy - 每次都尽量装两杯满水int res 0;priority_queueint heap; // 大根堆for (auto x: amount)heap.push(x);while (heap.size()){int t1 heap.top();heap.pop();int t2 heap.top();heap.pop();if (!t1) break; // 当前队列最大值是 0 说明所有 amount 都装满了 if (t1 1 t2 1){heap.push(t1 - 1);heap.push(t2 - 1);}else if (t1 1 !t2){res t1;break;}res ;}return res;}
};