两数之和再进化--大餐计数(哈希表的利用)

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两数之和再进化--大餐计数(哈希表的利用)相关的知识,希望对你有一定的参考价值。

题目

在这里插入图片描述

题目解析

读完题目可能大部分人直接暴力两层循环开干,可惜只能通过一半,要是暴力法能过,那也不可能标记为中等题了。

转换思路:我们转换成:两数之和为2的幂的个数,一看到两数之和我们很快会想到利用哈希表的 O(n) 解决方案,我们通过哈希表的 key 记录已扫描过的值, value 记录相同值的个数,然后每次通过查找 target-nums[i] 即可算出两数之和为 target 的次数,而这道题就出现在这个 target 不是很确定,但它一定是2的幂,所以我们可以枚举2的幂为target得到答案!

  • 继续优化算法:
    由于我们每次都通过左移得到二的幂来枚举target,这样在数据很小的情况下明显不利,由于每次只取两个数的和来查看是否为 target ,而这两个数的和无论如何都不可能比最大的两数之和要大,所以我们可以先找出最大的那个数,然后 *2作为枚举target的上限.

优化前代码

注意:由于答案需要取模,所以记得每次加法都取模!
在这里插入图片描述

class Solution {
public:
const int MOD = 1e9+7;
    int countPairs(vector<int>& deliciousness) {
        int sz = deliciousness.size();
        long long count = 0;
        unordered_map<int,long long>check;
        for(int i=0;i<sz;i++){
            if(i>0)
           for(int j=0;j<31;j++){
               int p = 1<<j;
            auto t = check.find(p-deliciousness[i]);
            if(t!=check.end())
                count = (count+t->second)%MOD;
           }
           check[deliciousness[i]]++;
        }
        return count;
    }
};

优化后代码

在这里插入图片描述

class Solution {
public:
const int MOD = 1e9+7;
    int countPairs(vector<int>& deliciousness) {
        int sz = deliciousness.size();
        long long count = 0;
        int mx = *max_element(deliciousness.begin(),deliciousness.end());
        unordered_map<int,long long>check;
        for(int i=0;i<sz;i++){
            if(i>0)
           for(long long p = 1;p<=mx*2;p = p<<1){
            auto t = check.find(p-deliciousness[i]);
            if(t!=check.end())
                count = (count+t->second)%MOD;
           }
           check[deliciousness[i]]++;
        }
        return count;
    }
};

以上是关于两数之和再进化--大餐计数(哈希表的利用)的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript笔试题(js高级代码片段)

两数之和(哈希解法)

哈希表简单应用—两数之和

leetcode.1.两数之和

1.两数之和

leetcode 1.两数之和(暴力&哈希)