1711. 大餐计数


阅读量15

题目

1711. 大餐计数

https://leetcode-cn.com/problems/count-good-meals/

大餐 是指 恰好包含两道不同餐品 的一餐,其美味程度之和等于 2 的幂。

你可以搭配 任意 两道餐品做一顿大餐。

给你一个整数数组 deliciousness ,其中 deliciousness[i] 是第 i 道餐品的美味程度,返回你可以用数组中的餐品做出的不同 大餐 的数量。结果需要对 109 + 7 取余。

注意,只要餐品下标不同,就可以认为是不同的餐品,即便它们的美味程度相同。

示例 1:

输入:deliciousness = [1,3,5,7,9] 输出:4 解释:大餐的美味程度组合为 (1,3) 、(1,7) 、(3,5) 和 (7,9) 。 它们各自的美味程度之和分别为 48816 ,都是 2 的幂。

示例 2:

输入:deliciousness = [1,1,1,3,3,3,7] 输出:15 解释:大餐的美味程度组合为 3 种 (1,1) ,9 种 (1,3) ,和 3 种 (1,7) 。

提示:

  • 1 <= deliciousness.length <= 105
  • 0 <= deliciousness[i] <= 220

题解

思路

哈希,存储出现过的数字次数,如果有出现则加上出现的次数。先计算出2的前22个幂的值,然后用减法,从哈希中获取是否有存在值。时间复杂度是O(n*22)

代码

/** * @param {number[]} deliciousness * @return {number} */ // 提前计算前21个值 const pow = []; for (let i = 0; i <= 21; i++) { pow.push(2 ** i); } var countPairs = function (deliciousness) { const n = deliciousness.length; const MOD = 10 ** 9 + 7; let hash = new Map(); // 把数组第一个加到哈希中 hash.set(deliciousness[0], 1) let ans = 0; let res; // 数组从1开始 for (let i = 1; i < n; i++) { // 对前21个值进行遍历,如果有在hash中出现过,那就加上该值出现过的次数 for (let j = 0; j <= 21; j++) { res = pow[j] - deliciousness[i]; if (hash.has(res)) { ans = (ans + hash.get(res)) % MOD; } } // 判断完之后,把当前值加到hash中 hash.set(deliciousness[i], (hash.get(deliciousness[i]) || 0) + 1) } return ans; };

czbiao 2021年7月8日 00:40 收藏文档
本站总访问量10362
本站访客数10291人次