返回介绍

solution / 1700-1799 / 1705.Maximum Number of Eaten Apples / README

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

1705. 吃苹果的最大数目

English Version

题目描述

有一棵特殊的苹果树,一连 n 天,每天都可以长出若干个苹果。在第 i 天,树上会长出 apples[i] 个苹果,这些苹果将会在 days[i] 天后(也就是说,第 i + days[i] 天时)腐烂,变得无法食用。也可能有那么几天,树上不会长出新的苹果,此时用 apples[i] == 0days[i] == 0 表示。

你打算每天 最多 吃一个苹果来保证营养均衡。注意,你可以在这 n 天之后继续吃苹果。

给你两个长度为 n 的整数数组 daysapples ,返回你可以吃掉的苹果的最大数目_。_

 

示例 1:

输入:apples = [1,2,3,5,2], days = [3,2,1,4,2]
输出:7
解释:你可以吃掉 7 个苹果:
- 第一天,你吃掉第一天长出来的苹果。
- 第二天,你吃掉一个第二天长出来的苹果。
- 第三天,你吃掉一个第二天长出来的苹果。过了这一天,第三天长出来的苹果就已经腐烂了。
- 第四天到第七天,你吃的都是第四天长出来的苹果。

示例 2:

输入:apples = [3,0,0,0,0,2], days = [3,0,0,0,0,2]
输出:5
解释:你可以吃掉 5 个苹果:
- 第一天到第三天,你吃的都是第一天长出来的苹果。
- 第四天和第五天不吃苹果。
- 第六天和第七天,你吃的都是第六天长出来的苹果。

 

提示:

  • apples.length == n
  • days.length == n
  • 1 <= n <= 2 * 104
  • 0 <= apples[i], days[i] <= 2 * 104
  • 只有在 apples[i] = 0 时,days[i] = 0 才成立

解法

方法一:贪心 + 优先队列

我们可以贪心地在未腐烂的苹果中优先选择最容易腐烂的苹果,这样可以使得吃到的苹果尽可能多。

因此,我们可以用优先队列(小根堆)存储苹果的腐烂时间以及对应苹果的数量,每次从优先队列中取出腐烂时间最小的苹果,然后将其数量减一,若减一后苹果的数量不为零,则将其重新放入优先队列中。若苹果已经腐烂,则从优先队列中弹出。

时间复杂度 $O(n\times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 applesdays 的长度。

class Solution:
  def eatenApples(self, apples: List[int], days: List[int]) -> int:
    n = len(days)
    i = ans = 0
    q = []
    while i < n or q:
      if i < n and apples[i]:
        heappush(q, (i + days[i] - 1, apples[i]))
      while q and q[0][0] < i:
        heappop(q)
      if q:
        t, v = heappop(q)
        v -= 1
        ans += 1
        if v and t > i:
          heappush(q, (t, v))
      i += 1
    return ans
class Solution {
  public int eatenApples(int[] apples, int[] days) {
    PriorityQueue<int[]> q = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
    int n = days.length;
    int ans = 0, i = 0;
    while (i < n || !q.isEmpty()) {
      if (i < n && apples[i] > 0) {
        q.offer(new int[] {i + days[i] - 1, apples[i]});
      }
      while (!q.isEmpty() && q.peek()[0] < i) {
        q.poll();
      }
      if (!q.isEmpty()) {
        var p = q.poll();
        ++ans;
        if (--p[1] > 0 && p[0] > i) {
          q.offer(p);
        }
      }
      ++i;
    }
    return ans;
  }
}
using pii = pair<int, int>;

class Solution {
public:
  int eatenApples(vector<int>& apples, vector<int>& days) {
    priority_queue<pii, vector<pii>, greater<pii>> q;
    int n = days.size();
    int ans = 0, i = 0;
    while (i < n || !q.empty()) {
      if (i < n && apples[i]) q.emplace(i + days[i] - 1, apples[i]);
      while (!q.empty() && q.top().first < i) q.pop();
      if (!q.empty()) {
        auto [t, v] = q.top();
        q.pop();
        --v;
        ++ans;
        if (v && t > i) q.emplace(t, v);
      }
      ++i;
    }
    return ans;
  }
};
func eatenApples(apples []int, days []int) int {
  var h hp
  ans, n := 0, len(apples)
  for i := 0; i < n || len(h) > 0; i++ {
    if i < n && apples[i] > 0 {
      heap.Push(&h, pair{i + days[i] - 1, apples[i]})
    }
    for len(h) > 0 && h[0].first < i {
      heap.Pop(&h)
    }
    if len(h) > 0 {
      h[0].second--
      if h[0].first == i || h[0].second == 0 {
        heap.Pop(&h)
      }
      ans++
    }
  }
  return ans
}

type pair struct {
  first  int
  second int
}

type hp []pair

func (a hp) Len() int       { return len(a) }
func (a hp) Swap(i, j int)    { a[i], a[j] = a[j], a[i] }
func (a hp) Less(i, j int) bool { return a[i].first < a[j].first }
func (a *hp) Push(x any)    { *a = append(*a, x.(pair)) }
func (a *hp) Pop() any      { l := len(*a); t := (*a)[l-1]; *a = (*a)[:l-1]; return t }

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

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

发布评论

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