LeetCode 算法基础之计数法(C++)

本文探讨了LeetCode中的四个经典问题,涉及计数法技巧:找出唯一元素的和、查找第一个唯一字符、判断字符出现次数是否相同,以及寻找数组中消失的数字。通过实例解析和源码展示,理解如何高效利用计数数组解决这些问题。
摘要由CSDN通过智能技术生成

目录

1748.唯一元素的和

题目描述

在这里插入图片描述
在这里插入图片描述

原题链接

唯一元素的和

思路点拨

nums数组中每个元素的值都在[1,100]中,因此我们可以创建一个大小为101
个空间的数组arr[101]来存储nums中的每个值的个数,用nums的值作为arr的下标,然后用一个循环遍历nums来初始化arr,最后累加arr数组值为1的下标即可(arr数组的下标即为nums中的值)

源码解析

class Solution {
public:
    int sumOfUnique(vector<int>& nums) {
        int sum=0;
        int arr[101]={};//把数组的每个元素都初始化为0
        for(int i=0;i<nums.size();++i)//
        {
            ++arr[nums[i]];//记录nums中每个数的数量
        }
        for(int i=0;i<101;++i)
        {
            if(arr[i]==1)//当数量为1时,就是我们需要累加的数
            sum+=i;
        }
        return sum;
    }
};

387.字符串中第一个唯一字符

题目描述

在这里插入图片描述

原题链接

387.字符串中第一个唯一字符

思路点拨

题目只要求测试小写字母即可,因此我们创建一个26个空间的数组,和上题差不多,唯一要注意的是,在计数时,每个字母要减97,如 ‘a’-97==0,所以在下标为0的位置存储 ‘a’ 的个数,其他字母同理

源码解析

class Solution {
public:
    int firstUniqChar(string s) {
        int pos=-1;//初始化位置为-1,方便没查找到时返回-1
        int arr[26]={};//申请26个空间用于存储26个小写字母的个数,初始化个数均为0
        for(int i=0;i<s.size();++i)
        {
            ++arr[s[i]-97];//循环计算每个字母的个数,'a'的ACKII码值为97,所以需要每个字符-97
        }
        for(int i=0;i<s.size();++i)
        {
            if(arr[s[i]-97]==1)//当遍历到数量为1的字母时,返回位置
            {
                pos=i;
                return pos;
            }
        }
        return pos;//没有符合条件的,返回-1
    }
};

1941.检测是否所有字符出现的次数相同

题目描述

在这里插入图片描述

原题链接

1941.检测是否所有字符出现的次数相同

思路点拨

此题和上题基本一致,细微之处的变动看源码解析即可

源码解析

class Solution {
public:
    bool areOccurrencesEqual(string s) {
        int arr[26]={};//申请26个空间用于存储26个小写字母的个数,初始化个数均为0
        for(int i=0;i<s.size();++i)
        {
            ++arr[s[i]-97];//循环计算每个字母的个数,'a'的ACKII码值为97,所以需要每个字符-97
        }
        int count=arr[s[0]-97];//以第一个字母的个数为标准
        for(int i=0;i<s.size();++i)
        {
            if(arr[s[i]-97]!=count)//当其中某一个字母的个数不等于该标准时,返回false
            return false;
        }
        return true;
    }
};

448.找到所有数组中消失的数字

题目描述

在这里插入图片描述

原题链接

448.找到所有数组中消失的数字

思路点拨

我们发现数组nums的最大值计数nums的长度,因此我们可以把nums本身作为一个哈希表,将数组元素对应为索引的位置加n,遍历加n后的数组,若数组元素值小于等于n,则说明数组下标值不存在,即消失的数字

源码解析

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        int n=nums.size();
        for(int i=0;i<n;++i)
        {
            //nums值的区间为[1,n],将其减1,才能与本身的下标匹配
            //取余n是为了还原,已经加了n的数
            int x=(nums[i]-1)%n;
            nums[x]+=n;
        }
        vector<int> ret;//开辟一个数组,用于存储需要返回的数
        for(int i=0;i<n;++i)
        {
            if(nums[i]<=n) //需要的是范围内没有出现的数,也就是小于等于n的数
            ret.push_back(i+1);
        }
        return ret;
    }
};

1512.好数对的数目

题目描述

在这里插入图片描述
在这里插入图片描述

原题链接

1512.好数对的数目

思路点拨

还是用哈希表来解,唯一需要注意的是好数对的定义及推论,n 个相同的数字,那么它的 好数对的个数为n*(n-1)/2

源码解析

class Solution {
public:
    int numIdenticalPairs(vector<int>& nums) {
        int count=0;
        int arr[100]={};//建立一个哈希数组,并初始化为0
        for(int i=0;i<nums.size();++i)
        {
            ++arr[nums[i]-1];//初始化哈希表
        }
        for(int i=0;i<100;++i)
        {
            count+=arr[i]*(arr[i]-1)/2;//计数,一个数出现n次,那它的好数对个数为n*(n-1)/2
        }
        return count;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

&不逝

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

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

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

打赏作者

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

抵扣说明:

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

余额充值