【跟着英雄学算法第⑤天】计数法——附Leetcode刷题题解(C语言实现)

✨前言✨

       在这个系列中,博主准备分享每日在万人千题社区打卡学习的算法。博主也是小白,因此也很能理解新手在刷题时的困惑,所以关注博主,每天学习一道算法吧。同时也欢迎大家加入万人千题习活动,正所谓:一个人可以走的很快,但一群人才能走的更远。

万人千题打卡社区https://bbs.csdn.net/forums/hero?category=0&typeId=17913


目录

一、算法思想笔记

二、唯一元素的和             ⭐

三、字符串中唯一字符      ⭐

四、大餐问题                    ⭐⭐

五、课后作业


一、算法思想笔记

我们知道,通过for循环,可以用一个计数变量计数出某个数出现多少次。那么如何反应一组数的数据分布呢?桶计数就是我们可以尝试的方法。(和博主高中学的桶排序很像,就用桶的方式为大家演示)

现假设有一组数据的范围在0~5,我们开辟5个“桶”,与每个数一一对应,来对其计数。什么意思呢,我们画个图来理解。

 其实很简单,在我们遍历数组的过程中,将数字“对号入座”即可,cnt[i]只存放数值为i的数的个数

有了基础的知识我们就可以开始刷题了

二、唯一元素的和   ⭐

1748. 唯一元素的和https://leetcode-cn.com/problems/sum-of-unique-elements/https://leetcode-cn.com/problems/sum-of-unique-elements/①问题呈现

 ②代码操练

int sumOfUnique(int* nums, int numsSize)
{
    int i=0;
    int sum=0;
    int cnt[101];//(1)
    memset(cnt, 0, sizeof(cnt));//(2)
    for(i=0;i<numsSize;i++)
    {
        cnt[nums[i]]++;//(3)
    }
    for(i=0;i<101;i++)
    {
        if(cnt[i]==1)
        {
            sum+=i;//(4)
        }
    }
    return sum;
}

 ③分析

1.要开辟101个桶,考虑到数组下标从0开始

2.用memset函数为计数数组的每一个“桶”初始值赋为0

3.数字“对号入座”,进行计数

4.根据题目要求只相交满足要求的“桶”

三、字符串中唯一字符      ⭐

387. 字符串中的第一个唯一字符https://leetcode-cn.com/problems/first-unique-character-in-a-string/icon-default.png?t=L9C2https://leetcode-cn.com/problems/first-unique-character-in-a-string/

①题目呈现

 ②代码操练

int firstUniqChar(char * s)
{
    int i=0;
    int size=strlen(s);
    int cnt[27];
    memset(cnt,0,sizeof(cnt));
    for(i=0;i<size;i++)
    {
        cnt[s[i]-96]++;
    }
    for(i=0;i<size;i++)
    {
        if(cnt[s[i]-96]==1)
        return i;
    }
    return -1;

}

   ③分析

这道题目的思想和上一道题目完全一致,这里不再赘述。     

四、大餐问题   ⭐⭐

1711. 大餐计数https://leetcode-cn.com/problems/count-good-meals/icon-default.png?t=L9C2https://leetcode-cn.com/problems/count-good-meals/

① 题目呈现

②思路点拨

 ③代码操练

int countPairs(int* deliciousness, int deliciousnessSize)
{
    int i=0;
    int sum=0;
    int other =0;
    int cnt[1<<21+1];//(1)
    int ans=0;
    memset(cnt, 0, sizeof(cnt));//(2)

    for(i = 0;i < deliciousnessSize;i++)//(3)
    {
        for(sum = 1;sum <= (1<<21) ;sum *= 2)//(4)
        {
            other= sum- deliciousness[i];//(5)
            if (other < 0)
            {                          
                continue;
            }
            ans += cnt[other];                     
            ans %= 1000000007;//(6)
        }
        cnt[deliciousness[i]]++;(7)
    }
    return ans;
}

思想: 

由于题目规定每一道菜都不一样,所以我们需要桶计数出,这道菜对应各种可能的sum,分别所需要的other有多少个。所以我们的基本思想是用桶记录各种other有多少个。

 解释:

1.考虑到other最大为2^21-1,所以cnt创建的大小应该为[(1 << 21) + 1]而不是(1 << 20) + 1]

2.为每个桶初始化内容为0

3.遍历每一道菜

4.遍历每一种sum

5.判断other是否存在

6.根据题目要求需要取余

 五、课后作业

1941. 检查是否所有字符出现次数相同⭐https://leetcode-cn.com/problems/check-if-all-characters-have-equal-number-of-occurrences/icon-default.png?t=L9C2https://leetcode-cn.com/problems/check-if-all-characters-have-equal-number-of-occurrences/448. 找到所有数组中消失的数字⭐https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/icon-default.png?t=L9C2https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/1512. 好数对的数目⭐⭐https://leetcode-cn.com/problems/number-of-good-pairs/icon-default.png?t=L9C2https://leetcode-cn.com/problems/number-of-good-pairs/

Guess you like

Origin blog.csdn.net/whc18858/article/details/120972348