Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Count Good Meals in Python
A good meal 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 arr where arr[i] is the deliciousness of the ith item of food, we need to return the number of different good meals you can make from this list.
Examples
Input-1 −
arr = [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.
Input-2 −
arr = [1, 1, 1, 3, 3, 3, 7]
Output −
15
Explanation − The good meals are (1,1) in 3 ways, (1,3) in 9 ways, and (1,7) in 3 ways.
Approach
The key insight is that for each element, we need to find how many previously seen elements can pair with it to form a power of 2 sum ?
Use a frequency map to count occurrences of each element
For each element, check all possible powers of 2 that could be formed
Count pairs where the complement exists in our frequency map
Apply modulo to handle large results
Implementation
from collections import defaultdict
from typing import List
class Solution:
def countpairs(self, arr: List[int]) -> int:
MOD = 10**9 + 7
result = 0
seen = defaultdict(int)
for num in arr:
# Check all powers of 2 up to 2 * max_possible_value
power = 1
while power <= num + max(arr):
complement = power - num
if complement in seen:
result = (result + seen[complement]) % MOD
power <<= 1 # Next power of 2
seen[num] += 1
return result
# Test with examples
sol = Solution()
print("Example 1:", sol.countpairs([1, 3, 5, 7, 9]))
print("Example 2:", sol.countpairs([1, 1, 1, 3, 3, 3, 7]))
Example 1: 4 Example 2: 15
Optimized Solution
Here's a cleaner implementation that handles the constraint more efficiently ?
from collections import defaultdict
def count_good_meals(arr):
MOD = 10**9 + 7
result = 0
freq = defaultdict(int)
for num in arr:
# Check powers of 2 from 2^0 to 2^21 (max constraint)
power = 1
for i in range(22): # 2^21 is the max we need
complement = power - num
if complement >= 0 and complement in freq:
result = (result + freq[complement]) % MOD
power <<= 1
freq[num] += 1
return result
# Test examples
print("Test 1:", count_good_meals([1, 3, 5, 7, 9]))
print("Test 2:", count_good_meals([1, 1, 1, 3, 3, 3, 7]))
print("Test 3:", count_good_meals([1, 2, 3, 4]))
Test 1: 4 Test 2: 15 Test 3: 2
How It Works
For each element in the array:
We iterate through all possible powers of 2 (1, 2, 4, 8, 16, ...)
For each power, we calculate the complement that would sum to this power
If the complement exists in our frequency map, we add its count to our result
We then add the current element to our frequency map
Time Complexity
The time complexity is O(n × log(max_value)) where n is the length of the array, since we check at most 22 powers of 2 for each element.
Conclusion
This approach efficiently counts good meals by using a frequency map and checking all possible power-of-2 sums. The key insight is to process elements sequentially and count valid complements from previously seen elements.
