package LeetCode_1711 /** * 1711. Count Good Meals * https://leetcode.com/problems/count-good-meals/ * A good meal is a meal that contains exactly two different food items with a sum of deliciousness equal to a power of two. You can pick any two different foods to make a good meal. Given an array of integers deliciousness where deliciousness[i] is the deliciousness of the ith item of food, return the number of different good meals you can make from this list modulo 10^9 + 7. Note that items with different indices are considered different even if they have the same deliciousness value. Example 1: Input: deliciousness = [1,3,5,7,9] Output: 4 Explanation: The good meals are (1,3), (1,7), (3,5) and, (7,9). Their respective sums are 4, 8, 8, and 16, all of which are powers of 2. Example 2: Input: deliciousness = [1,1,1,3,3,3,7] Output: 15 Explanation: The good meals are (1,1) with 3 ways, (1,3) with 9 ways, and (1,7) with 3 ways. Constraints: 1. 1 <= deliciousness.length <= 10^5 2. 0 <= deliciousness[i] <= 2^20 * */ class Solution { /* * solution 1: bruce force, Time:O(n^2), TLE; * solution 2: HashMap, TwoSum solution, Time:O(n), Space:O(n); * */ fun countPairs(deliciousness: IntArray): Int { var result = 0 //solution 1: /*for (i in deliciousness.indices) { for (j in i until deliciousness.size) { if (i != j) { if (isPowOfTwo(deliciousness[i] + deliciousness[j])) { result++ } } } }*/ //solution 2: val mod = 1000000007 //key:num, value:the number of times (target-num) occurrence val map = HashMap<Int, Int>() for (num in deliciousness) { var power = 1 //handle int32, because 0 <= deliciousness[i] <= 2^20 for (i in 0..31) { //power just like a target, because (1+3=4) or (1+7=8), they are sum are powers of 2, so have to find (power-num) val needToFind = power - num if (map.containsKey(needToFind)) { result += map.get(needToFind)!! result %= mod } power *= 2 } map.put(num, map.getOrDefault(num, 0) + 1) } return result } private fun isPowOfTwo(n_: Int): Boolean { var n = n_ if (n == 0) { return false } while (n != 1) { if (n % 2 != 0) { return false } n /= 2 } return true } }