力扣刷题-1711.大餐技术

题目

题解

typedef struct {
    int key;
    int num;
    UT_hash_handle hh;
} HashNode, *HashTable;

int countPairs(int* deliciousness, int deliciousnessSize){
    //预设结果,2的幂次
    int result[22];
    for(int i = 0; i < 22; i++){
        if(i == 0){
            result[i] = 1;
        }else {
            result[i] = result[i-1]*2;
        }
    }
    //创建哈希表将所有元素存进哈希表中
    HashTable ht = NULL;
    for(int i = 0; i < deliciousnessSize; i++){
        HashNode * temp = NULL;
        HASH_FIND_INT(ht,&deliciousness[i],temp);
        if(temp == NULL){
            temp = (HashNode*)malloc(sizeof(HashNode));
            temp->key = deliciousness[i];
            temp->num = 1;
            HASH_ADD_INT(ht,key,temp);
        }else{
            temp->num += 1;
        }
    }
    //遍历数组
    long count = 0;
    for(int i = 0; i < deliciousnessSize; i++){
        for(int j = 0; j < 22; j++){
            int target = result[j] - deliciousness[i];
            HashNode * temp = NULL;
            HASH_FIND_INT(ht,&target,temp);
            if(temp != NULL){
                if(temp->key != deliciousness[i]){
                    //count = (count + temp->num) % 1000000007;
                    count += temp->num;
                }else{
                    //count = (count + temp->num - 1) % 1000000007;
                    count += temp->num - 1;
                }
            }
        }
    }
    //最后要除以2
    count = count / 2;
    count %= 1000000007;
    return count;
}

心得

最近遇到很多问题,又有了一点经验和做算法题的思路。

看到一个题目:

  1. 首先应该考虑输入与输出,思考数的范围。

  1. 其次思考算法。

  1. 然后再思考算法中使用到的数据结构。

本题要点

  1. 首先看到给的数据个数10^5数量级,然后再看数据范围0~2^20。

  1. 思考算法:如果使用双循环的话时间复杂度是10^10,大概率会超时。可以使用哈希表来做,现将所有的元素存入哈希表中,再依次遍历每个元素寻找是否有另一个元素与本元素之和是2的幂次。

  1. 哈希表的结构应包含键值与键值出现的个数。

  1. 其他细节①:2的幂次可以事先存储在一个数组中,从数据范围可以得知,最小的2的幂次是2^0=1,最大的幂次是2^20+2^20=2^21。因此设置一个大小为22的数组result,将result[0]设置为1,后续遍历result[i]=result[i-1]*2即可得到所有的2的幂次。

  1. 其他细节②:在计算结果时,并不是加上一个数就对1000000007取余,不然可能中间结果值刚超过1000000007就取余了然后后面就乱了....,而是要最后所有次数都加上之后再进行取余。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东东咚咚东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值