小扣在秋日市集选择了一家早餐摊位,一维整型数组 staple 中记录了每种主食的价格,一维整型数组 drinks 中记录了每种饮料的价格。小扣的计划选择一份主食和一款饮料,且花费不超过 x 元。请返回小扣共有多少种购买方案。
注意:答案需要以 1e9 + 7 (1000000007) 为底取模,如:计算初始结果为:1000000008,请返回 1
掌握:二分查找:返回二分查找到的第一个关键字的下标,不考虑后面是否有相同的关键字,因为咋们是二分的;若没有该关键字,插入并返回-index-1,表示插入的位置。
思路:想二分,先排序。
之后先找到Staple数组中<=x的下标(这里二分查找的关键字比题目要求的"花费不超过”x要大1,这样避免了:多个值一样的关键字,但只返回前一个而忽略后面的情况;最后下标往前移一个就是符合要求的下标)
在循环里面,通过target = x - staple[i] 去找drinks中符合的最大下标tempDrinks。而tempDrinks的值+1就是当前 staple[ i ]所对应drinks的购买方案。
class Solution {
public int breakfastNumber(int[] staple, int[] drinks, int x) {
Arrays.sort(staple);
Arrays.sort(drinks);
/*
* 二分查栈要考虑两种情况: 一种是本身存在关键字,返回第一个关键字的下标,但后面可能也存在相同的关键字——解决方法:找比关键字略大一个的数
* 一种是不存在关键字,返回硬插入元素的下标
*/
long count = 0;
int index = Arrays.binarySearch(staple, x + 1);
if (index < 0) {
index = (index + 1) * (-1);
}
index--;
for (int i = 0; i <= index; i++) {
int tempDrinks = Arrays.binarySearch(drinks, x - staple[i]);
// 考虑后面也存在相同关键字的可能
if (tempDrinks < 0) {
tempDrinks = (tempDrinks + 1) * (-1);
tempDrinks--;
} else {
while (tempDrinks < drinks.length-1 && drinks[tempDrinks] == drinks[tempDrinks + 1]) {
tempDrinks++;
}
}
count += tempDrinks + 1;
count %= 1000000007;
}
return (int) count;
}
}
end.