返回介绍

solution / 2300-2399 / 2335.Minimum Amount of Time to Fill Cups / README

发布于 2024-06-17 01:03:07 字数 4827 浏览 0 评论 0 收藏 0

2335. 装满杯子需要的最短总时长

English Version

题目描述

现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 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

解法

方法一:贪心 + 排序

我们可以每次贪心地选择其中较大的两个数进行减一操作(最多减为 $0$),直至所有数变为 $0$。

时间复杂度 $O(S)$,空间复杂度 $O(1)$。其中 $S$ 为数组 amount 中所有数的和,本题中 $S \leq 300$。

class Solution:
  def fillCups(self, amount: List[int]) -> int:
    ans = 0
    while sum(amount):
      amount.sort()
      ans += 1
      amount[2] -= 1
      amount[1] = max(0, amount[1] - 1)
    return ans
class Solution {
  public int fillCups(int[] amount) {
    int ans = 0;
    while (amount[0] + amount[1] + amount[2] > 0) {
      Arrays.sort(amount);
      ++ans;
      amount[2]--;
      amount[1] = Math.max(0, amount[1] - 1);
    }
    return ans;
  }
}
class Solution {
public:
  int fillCups(vector<int>& amount) {
    int ans = 0;
    while (amount[0] + amount[1] + amount[2]) {
      sort(amount.begin(), amount.end());
      ++ans;
      amount[2]--;
      amount[1] = max(0, amount[1] - 1);
    }
    return ans;
  }
};
func fillCups(amount []int) int {
  ans := 0
  for amount[0]+amount[1]+amount[2] > 0 {
    sort.Ints(amount)
    ans++
    amount[2]--
    if amount[1] > 0 {
      amount[1]--
    }
  }
  return ans
}
function fillCups(amount: number[]): number {
  amount.sort((a, b) => a - b);
  let [a, b, c] = amount;
  let diff = a + b - c;
  if (diff <= 0) return c;
  else return Math.floor((diff + 1) / 2) + c;
}
impl Solution {
  pub fn fill_cups(mut amount: Vec<i32>) -> i32 {
    amount.sort();
    let dif = amount[0] + amount[1] - amount[2];
    if dif <= 0 {
      return amount[2];
    }
    (dif + 1) / 2 + amount[2]
  }
}

方法二:贪心 + 分类讨论

我们可以将数组 amount 排序,设 $a$, $b$, $c$ 分别为数组 amount 中的三个数,有以下两种情况:

  • 如果 $a + b \leq c$,此时我们只需要 $c$ 次操作即可将所有数变为 $0$,因此答案为 $c$。
  • 如果 $a + b > c$,每一次操作我们都可以将其中两个数减一,最终匹配完,或者剩下最后一个数(取决于总和是偶数还是奇数),因此答案为 $\left \lfloor \frac{a + b + c + 1}{2} \right \rfloor$。

时间复杂度 $O(1)$,空间复杂度 $O(1)$。

class Solution:
  def fillCups(self, amount: List[int]) -> int:
    amount.sort()
    if amount[0] + amount[1] <= amount[2]:
      return amount[2]
    return (sum(amount) + 1) // 2
class Solution {
  public int fillCups(int[] amount) {
    Arrays.sort(amount);
    if (amount[0] + amount[1] <= amount[2]) {
      return amount[2];
    }
    return (amount[0] + amount[1] + amount[2] + 1) / 2;
  }
}
class Solution {
public:
  int fillCups(vector<int>& amount) {
    sort(amount.begin(), amount.end());
    if (amount[0] + amount[1] <= amount[2]) {
      return amount[2];
    }
    return (amount[0] + amount[1] + amount[2] + 1) / 2;
  }
};
func fillCups(amount []int) int {
  sort.Ints(amount)
  if amount[0]+amount[1] <= amount[2] {
    return amount[2]
  }
  return (amount[0] + amount[1] + amount[2] + 1) / 2
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文