力扣-2671-频率跟踪器-题解

1. 问题描述

2. 思路分析

由于本题不需要我们输出add的number,所以我们无需将他们存储起来。由于题目要求我们判断数据结构中是否存在出现 frequency 次的数字,因此我们可以用两个数组,一个数组num1用于存储该数字出现的次数,add一次,则在num1索引为number的元素++;另一个数组num2则用来存储相同数量的number的个数,有n个number它们存在的数量一样,则在对应数量为索引的元素+n,若number为1和5出现的次数都为3,则使数组索引为3的元素为2。因此当我们添加时,我们要先把num2[num1[number]++]--(n=num1[number]即是number出现的次数,num2[n]--即是把先前对应出现次数为n的number的个数-1(先前可能是2和3都出现了2次,但是现在要add3,即出现2次的就只有2了,所以要--),然后再把number出现的次数n++(也就是说现在3出现了3次了)),再把num2[num1[number]]++(即是把出现n++次的number个数+1,也就是说因为3现在也出现了3次,所以出现3次的number个数要+1);删除时,如果number出现的次数为0,无需操作,否则先把num2[num1[number]--]--,再num2[num1[number]]++;这两步操作跟添加时道理是一样的。

3. 算法描述

(1)创建两个空数组num1和num2,并将它们的元素初始化为0
(2)添加:num2[num1[number]++]--;num2[num1[number]]++;
(3)删除:先判断number出现的次数是否为0,是则无需操作,否则num2[num1[number]--]--;num2[num1[number]]++;
(4)返回num2[frequency],它的值即对应所要查找的出现次数相同的number的个数(题目有一个就为true),若==0说明没有一个number出现的次数符合题意,则bool为flase;若>0则bool为true

4. 代码实现

class FrequencyTracker {
public:
    int num1[200001];  //number出现的次数
    int num2[200001];  //有多少个number出现同样的次数:比如有多少个number出现1次,num[2]的值代表出现2次的数number有多少个
    FrequencyTracker() {
        memset(num2,0,sizeof(int)*200001);  //初始化num2和num1,使它们全部元素为0
        memset(num1,0,sizeof(int)*200001);
    }

    void add(int number) {
        num2[num1[number]++]--;  //若num1[number]为0,此时num2[0]--可能变成负数,但由于frequency>=1,无需用到num2[0]所以无需特殊操作
        num2[num1[number]]++;
    }

    void deleteOne(int number) {
        if(num1[number]==0)return;  //若number出现的次数为0,则无需删除操作
        num2[num1[number]--]--;
        num2[num1[number]]++;
    }

    bool hasFrequency(int frequency) {
        return num2[frequency];
    }
};



/**
 * Your FrequencyTracker object will be instantiated and called as such:
 * FrequencyTracker* obj = new FrequencyTracker();
 * obj->add(number);
 * obj->deleteOne(number);
 * bool param_3 = obj->hasFrequency(frequency);
 */


5.分析与总结 

该程序单次添加和删除以及查找的时间复杂度均为O(1);
注意:由于此题无需我们输出每一个number的值,因此无需将其值储存起来

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值