数组中数字出现的次数

Posted 小写丶H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组中数字出现的次数相关的知识,希望对你有一定的参考价值。

这里就把这一类出现过的问题统一解决一下

数组中数字出现的次数

I.一个整型数组nums中,其他数出现两次,只有一个数出现了一次。

思路

相对简单,我们直接可以想到用异或的方式解决。
因为我们知道
a^a=0
a^0=a
所以可以达到很好的去重效果。

代码

public int singleNumber(int[] nums) 
        int n=0;
        //这题相对简单我们只需要异或整个数组即可了
        for (int x:nums)
            n^=x;
        
        return  n;

II.一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。

思路

我觉得这题还是有点数学逻辑的意思。
1.先把数组遍历一遍 异或到num中
2.num中存放的就是内两个出现一次的数的异或结果
num=a^b ^c ^c ^d ^d 可以化简成 num=a ^b;
3.找到标记位,(不相等的两个数异或之后低位出现的第一个不相同的位数)(一个标志位n,从右往左找。)
4.拿着这个n就可以对数组进行分组,那么a,与b一定会被分开。
具体的解决细节,代码中体现了。

代码

    public int[] singleNumbers(int[] nums) 
        int x=0,y=0,num=0,n=1;
        //把数组全部异或到num中
        for(int a:nums)
            num^=a;
        
        //找到 n 的位置,出现两次的都异或为零,出现一次的两个数字,异或必然有一位是不同的
        while((num&n)==0)
            n<<=1;
        
        for(int a:nums)
            //进行分组
            if((a&n)==0)
                x^=a;
            else
                y^=a;
            
        
        return new int[]x,y;
    

III.在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。

思路

这里我觉得直接用哈希表解决,这样直观也好理解。

代码

public int singleNumber(int[] nums) 
        //利用hash表解题
        Map<Integer,Integer> map=new HashMap<>();
        //存放到hash表中
        for (int i = 0; i <nums.length ; i++) 
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        
        //找到出现一次的
        for (Map.Entry<Integer,Integer> entry: map.entrySet())
            if (entry.getValue()==1)
                return entry.getKey();
            
        
        return -1;
    

以上是关于数组中数字出现的次数的主要内容,如果未能解决你的问题,请参考以下文章

如何求出数组中出现次数最多的数字(C#实现)

数组中次数超过数组长度一半的数字

求一个区间[a,b]中数字1出现的次数

数组中出现次数超过一半的数字-剑指Offer

数组中出现次数超过一半的数字

39 数组中出现次数超过一半的数字(时间效率)