一二三四五 上山打老虎

Leetcode每日一题-2021-7-7<大餐计数>(思维题)

链接:https://leetcode-cn.com/problems/count-good-meals/
1711. 大餐计数
题意:一个长度为1e5的数组,计算有多少对数字可以组成2的次方,结果对1e9+7取余,数组最大值为2e20
思路:根据题意,组成的2的次方num范围为[0,2e40],只需从0-40遍历2的次方即可,则我们可以遍历数组判断,很容易就会想到用map来存储数组方便计算num-d[i]的数目,未来防止重复计算,我们可以先计算再插入数值,相当于map中的序号都小于当前值的序号(思路参考官方题解),防止重复计算,时间复杂度约等于O(40n)<=40*1e5=4e6,当然可以根据数组中实际的最大值来进一步降低时间复杂度。

代码:

class Solution {
public:
    int countPairs(vector<int>& d) {
        map<int,int>m;
        const int mod=(int)1e9+7;
        int res=0;
        for(int i=0;i<d.size();i++){
            int num=d[i];
            long long ans=1;
            for(int j=1;j<40;j++){
                if(ans>num+(int)1e9)break;
                int atm=m.count(ans-num) ?m[ans-num]:0;
                res=(res+atm)%mod;
                ans*=2;
            }
            // cout<<num<<" "<<res<<endl;
            m[num]++;
        }
        return res;
    }
};
posted @ 2021-07-07 21:59  黒川川  阅读(55)  评论(0)    收藏  举报