LeetCode.早餐组合(Java)排序+二分查找

小扣在秋日市集选择了一家早餐摊位,一维整型数组 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.

猜你喜欢

转载自blog.csdn.net/weixin_44998686/article/details/108894106
今日推荐