大餐 是指 恰好包含兩道不同餐品 的一餐,其美味程度之和等于 2 的冪。
你可以搭配 任意 兩道餐品做一頓大餐。
給你一個整數數組 deliciousness ,其中 deliciousness[i] 是第 i?????????????? 道餐品的美味程度,返回你可以用數組中的餐品做出的不同 大餐 的數量。結果需要對 109 + 7 取余。
注意,只要餐品下標不同,就可以認為是不同的餐品,即便它們的美味程度相同。
示例 1:輸入:deliciousness = [1,3,5,7,9]
輸出:4
解釋:大餐的美味程度組合為 (1,3) 、(1,7) 、(3,5) 和 (7,9) 。
它們各自的美味程度之和分別為 4 、8 、8 和 16 ,都是 2 的冪。
示例 2:輸入:deliciousness = [1,1,1,3,3,3,7]
輸出:15
解釋:大餐的美味程度組合為 3 種 (1,1) ,9 種 (1,3) ,和 3 種 (1,7) 。
解題思路
- 因為deliciousness[i]最大就是2的20次方,因此美味程度之和只有1到2的21次冪,共21種選擇
- 使用map記錄每個元素出現的次數
- 做出大餐的條件:deliciousness[i]+deliciousness[x]=2的n次冪,變形得deliciousness[x]=2的n次冪-deliciousness[i],因此我們可以遍歷2的n次冪,通過map找出deliciousness[x]的出現次數,即是做出大餐的次數
代碼
class Solution {public int countPairs(int[] deliciousness) {int two=1,mod=1000000007;ArrayList<Integer> list = new ArrayList<>();for (int i=0;i<=21;i++)list.add(two<<i);HashMap<Integer, Integer> map = new HashMap<>();map.put(deliciousness[0],1);Long res= 0L;for (int i=1;i<deliciousness.length;i++){for (Integer integer : list) {if(map.containsKey(integer-deliciousness[i]))res=(res+map.get(integer-deliciousness[i]))%mod;}map.put(deliciousness[i],map.getOrDefault(deliciousness[i],0)+1);}return (int)(res%(10e9+7));}
}