LeetCode 1711. 大餐计数

难度:中等。
标签:数组,哈希表。

使用字典存储美味值以及该值出现的个数。
将不重复的美味值放在list中并排序。
由于美味值的最大值为 2 20 2^{20} 220,因此两个食物的美味值之和最大为 2 21 2^{21} 221,将小于 2 22 2^{22} 222的幂计算出来存于mi数组中。
遍历list,list[i]与比其小的食物组合美味值取值范围位 [ l i s t [ i ] , l i s t [ i ] ∗ 2 ] [list[i], list[i] * 2] [list[i],list[i]2],因此找到该范围内的幂,减去list[i],得到x,根据x的出现次数更新组合个数。

正确解法:

class Solution {

    vector<int> getMi(){
        vector<int> arr(1, 1);
        int a = 1;
        for(int i = 1; i <= 22; ++i){
            a = a * 2;
            arr.emplace_back(a);
        }
        return arr;
    }


    int getNum(int a, int max){
        int ans = 0;
        for(int i = 1; i < a; ++i){
            ans += i;
            ans %= max;
        }
        return ans;
    }


public:
    int countPairs(vector<int>& deliciousness) {
        int ans = 0;
        int max = pow(10, 9) + 7;
        vector<int> mi = getMi();

        unordered_map<int, int> maps;
        for(int i = 0; i < deliciousness.size(); ++i){
            maps[deliciousness[i]]++;
        }
        vector<int> list;
        for(auto it = maps.begin(); it != maps.end(); ++it){
            list.emplace_back((*it).first);
        }
        sort(list.begin(), list.end());

        /*cout << "list: ";
        for(int i = 0; i < list.size(); ++i)cout << list[i] << " ";
        cout  << endl << endl;

        cout << "mi: ";
        for(int i = 0; i < mi.size(); ++i)cout << i << " " << mi[i] << endl;
        cout  << endl << endl;*/
        
        for(int i = list.size() - 1; i >= 0; --i){
            int left = -1, right = -1;
            for(int k = 0; k < mi.size(); ++k){
                if(left == -1 && mi[k] >= list[i])left = k;
                if(right == -1 && mi[k] > list[i] * 2){
                    right = k - 1;
                    break;
                }
            }
            // cout << list[i] << " " << left << " " << right << endl;
            for(int k = left; k <= right; ++k){
                int other = mi[k] - list[i];
                if(other == list[i]){
                    ans += getNum(maps[list[i]], max);
                    ans %= max;
                }
                else if(maps[other] > 0){
                    ans += maps[list[i]] * maps[other];
                    ans %=  max;
                }
            }
        }

        return ans;
    }
};

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值