早餐组合
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 149 ms, 内存: 31.0 MB
/*
* 思路:
* 1. 对主食数组 staple 进行排序。
* 2. 使用流操作遍历饮料数组 drinks,对于每一个饮料价格,使用二分查找在主食数组中找到可以搭配的最大主食价格。
* 3. 计算满足条件的主食数量并累加到总数中。
* 4. 最后对结果取模 1e9 + 7。
*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class BreakfastComboStream {
public int breakfastNumber(int[] staple, int[] drinks, int x) {
Arrays.sort(staple);
int MOD = 1000000007;
return IntStream.of(drinks).map(drink -> {
int maxStaple = x - drink;
if (maxStaple <= 0) return 0;
int left = 0, right = staple.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (staple[mid] <= maxStaple) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}).reduce(0, (a, b) -> (a + b) % MOD);
}
}
解释
方法:
这个题解采用了前缀和的思想加上一点优化来减少查找时间。首先,创建一个长度为x+1的数组arr,用于记录每个价格以下的主食数量。遍历主食数组staple,对于每个价格小于x的主食,增加arr中对应价格索引的计数。然后,对arr数组进行前缀和处理,使得arr[i]表示所有价格小于等于i的主食总数。接着,遍历饮料数组drinks,对每种饮料,计算其与主食组合的最大可接受价格x-drink。如果这个值大于0,那么直接从arr数组中得到所有价格小于等于这个值的主食数量,加到答案中。最后,由于可能出现计数非常大的情况,对最终结果取模1e9+7。
时间复杂度:
O(n + m + x)
空间复杂度:
O(x)
代码细节讲解
🦆
为什么在计算前缀和时,数组arr的起始索引是从2开始,而不是从1开始?
▷🦆
在处理饮料数组时,如果lt(x-drink)的值小于等于0,这种情况是如何处理的,它会对总方案数产生什么影响?
▷🦆
在实现中,对于超过x的主食价格,没有进行任何操作,这是否意味着价格超过x的主食在方案中完全不被考虑?这种处理是否合理?
▷