一、题目
大餐 是指 恰好包含两道不同餐品 的一餐,其美味程度之和等于 2
的幂。
你可以搭配 任意 两道餐品做一顿大餐。
给你一个整数数组 deliciousness
,其中 deliciousness[i]
是第 i
道餐品的美味程度,返回你可以用数组中的餐品做出的不同 大餐 的数量。结果需要对 10^9 + 7
取余。
注意,只要餐品下标不同,就可以认为是不同的餐品,即便它们的美味程度相同。
点击查看原题
难度级别: 中等
二、思路
1)哈希表
直接想到暴力法的求解,就是使用O(n^2)
时间复杂度进行遍历,把所有的组合都遍历一遍,就可以找到总的组合数量
为了减小时间复杂度,使用一个hashmap
来寻找在遍历过的数中,是否存在一个数与当前数之和为2的幂次方
,hashmap
中的键为美味程度数值,值为已经遍历的同美味程度菜肴数量;且两数之和小于等于最大值*2
三、代码
1)哈希表
class Solution {
public int countPairs(int[] deliciousness) {
long ans = 0;
Map<Integer, Integer> memo = new HashMap();
int maxVal = 0;
for (int i : deliciousness) { // 找到最大值
maxVal = Math.max(maxVal, i);
}
maxVal <<= 1;
for (int val : deliciousness) {
for (int i = 1; i <= maxVal; i <<= 1) {
if (i < val) { // 本题两个数之和一定大于或等于单独数值的
continue;
}
int needVal = i - val;
ans = (ans + (long)memo.getOrDefault(needVal, 0)) %1000000007;
}
memo.put(val, memo.getOrDefault(val, 0) + 1);
}
return (int)ans;
}
}
时间复杂度为O(nlogC)
,C
为最大值上限,空间复杂度为O(n)