1711. Count Good Meals

题目:

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 i​​​​​​th​​​​​​​​ item of food, return the number of different good meals you can make from this list modulo 109 + 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 <= deliciousness.length <= 10^5
  • 0 <= deliciousness[i] <= 2^20

 

 

 

思路:

题目意思其实就是给定一个可能有重复数字的数组,找出数组中任意两数相加所得和为2的幂的所有组合,返回组合数量,并不要求具体组合,其中相同数字的不同个体视为不同。这里数量级在10的5次,因此二重循环遍历数组不可取。有个比较tricky的地方,数组中数字小于等于2的20次,隐含的意思就是任意两数之和必然小于等于2的21次,这也是解题关键。首先无可避免的是用哈希表来存数字和出现几次,然后我们先循环2的0次到2的21次,每一轮都有一个2的幂,作为我们的target和。第二重循环我们再遍历哈希表,找出能和当前数相加为target的数是否存在。这里因为同一个数比如两个1,相加是2也是成立的,因此如果是这个数本身的话,我们不用除以2,我们用ans1来记录;如果不是,我们先算在答案ans2中,这部分的总和是要除以2的,因为我们循环a时找了b,循环b时又找了一次a,因此最终返回的是ans1+ans2/2。另外就是注意mode,和一开始我们初始化ans1和ans2可以用long long来避免int无法承接数字。

 

 

 

代码:

class Solution {
public:
    int countPairs(vector& d) {
        unordered_map m;
        int mod = 1e9+7;
        for(auto i:d)
        {
            m[i]++;
        } 
        long long ans1=0, ans2=0;
        for(int i=0;i<=21;i++)
        {
            int target=pow(2,i);
            for(auto itr=m.begin();itr!=m.end();itr++)
            {
                auto match=m.find(target-itr->first);
                if(match==m.end())
                    continue;
                if(match==itr)
                {
                    long long t=itr->second;
                    ans1+=(t*(t-1))/2;
                }
                else
                    ans2+=match->second*itr->second;
            }
            ans1%=mod;
            ans2%=mod;
        }
        return ans1+ans2/2;
    }
};

你可能感兴趣的:(LeetCode)