吃苹果的最大数目
难度:
标签:
题目描述
代码结果
运行时间: 151 ms, 内存: 20.4 MB
/*
* 思路:
* 1. 使用优先队列(PriorityQueue)来追踪苹果的数量和腐烂日期。
* 2. 每天移除已经腐烂的苹果。
* 3. 如果有新苹果生长,加入优先队列。
* 4. 如果有可以吃的苹果,吃一个并更新优先队列中的数量。
* 5. 使用Stream API处理数组元素。
*/
import java.util.*;
import java.util.stream.IntStream;
public class AppleEatingStream {
public int eatenApples(int[] apples, int[] days) {
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
int[] indices = IntStream.range(0, apples.length).toArray();
int day = 0;
int eaten = 0;
while (day < apples.length || !pq.isEmpty()) {
if (day < apples.length && apples[day] > 0) {
pq.offer(new int[]{day + days[day], apples[day]});
}
while (!pq.isEmpty() && pq.peek()[0] <= day) {
pq.poll();
}
if (!pq.isEmpty()) {
int[] current = pq.peek();
current[1]--;
if (current[1] == 0) {
pq.poll();
}
eaten++;
}
day++;
}
return eaten;
}
public static void main(String[] args) {
AppleEatingStream aes = new AppleEatingStream();
int[] apples = {1, 2, 3, 5, 2};
int[] days = {3, 2, 1, 4, 2};
System.out.println(aes.eatenApples(apples, days)); // 输出: 7
}
}
解释
方法:
题解采用了贪心算法和优先队列(最小堆)来解决问题。每天都会检查新长出的苹果并记录它们腐烂的日期和数量。使用最小堆是为了每天都能优先吃掉最先腐烂的苹果。堆中每个元素是一个列表,其中第一个元素是苹果腐烂的日期,第二个元素是苹果的数量。每天开始时,会移除所有已经腐烂的苹果。如果当天有新苹果,就将其添加到堆中。接着,如果堆不为空,表示还有未腐烂的苹果,就吃掉一个,并相应地更新堆。遍历完所有的天数后,还需要处理堆中剩余的苹果,直到所有的苹果都被吃完或腐烂。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在处理剩余苹果的循环中,如何确定循环终止的条件,并保证所有可以吃的苹果都被正确计算?
▷🦆
在每日移除腐烂苹果的过程中,如果存在多个苹果在同一天腐烂,算法是如何确保所有这些苹果都被及时移除的?
▷🦆
算法在添加新苹果到堆中时,是如何处理那些当天就会腐烂的苹果的?
▷🦆
考虑到每天只能吃一个苹果,当堆中存在多个苹果而其中一些即将在当天或次日腐烂时,算法是如何优先选择苹果的?
▷