剑指offer-004-只出现一次的数字

Posted zhixuChen333

tags:

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

目录标题

题目

输入一个整数数组,数组中只有一个数字出现了一次,而其他数字都出现了3次。请找出那个只出现一次的数字。例如,如果输入的数组为[0,1,0,1,0,1,100],则只出现一次的数字是100。

思路

1.将数组转换成Map结构,数字作为key,出现的次数为value,遍历map集合,返回value=1的key,这种做法很简单,但是效率也比较低。

2.一个整数是由32个0或1组成的。我们可以将数组中所有数字的同一位置的数位相加。如果将出现3次的数字单独拿出来,那么这些出现了3次的数字的任意第i个数位之和都能被3整除。因此,如果数组中所有数字的第i个数位相加之和能被3整除,那么只出现一次的数字的第i个数位一定是0;如果数组中所有数字的第i个数位相加之和被3除余1,那么只出现一次的数字的第i个数位一定是1。这样只出现一次的任意第i个数位可以由数组中所有数字的第i个数位之和推算出来。当我们知道一个整数任意一位是0还是1之后,就可以知道它的数值。

代码

解法1,暴力

   public int singleNumber(int[] nums) 
        Map<Integer,Integer> map = new HashMap();
        for (int i = 0; i < nums.length; i++) 
            if(!map.containsKey(nums[i]))
                map.put(nums[i],1);
            else 
                int a = map.get(nums[i]) + 1;
                map.put(nums[i],a);
            
        
        int x = 0;
        for (Map.Entry<Integer, Integer> i : map.entrySet()) 
            if (i.getValue() == 1) 
                x = i.getKey();
                break;
            
        
        return x;
    

解法2,运用位运算

  public int singleNumber(int[] nums) 
        int[] bitNums = new int[32];
        for(int num : nums)
            for (int i = 0; i < 32; i++) 
                bitNums[31 - i] += num >> (31 - i) & 1;
            
        
        int result = 0;
        for (int i = 0; i < 32; i++) 
            result += (bitNums[31 - i]%3) << (31 - i);
        
        return result;
    

说明:

  1. “ bitNums[31 - i] += num >> (31 - i) & 1”,判断每个数二进制数位是0或1,统计对应数位1的个数。

以上是关于剑指offer-004-只出现一次的数字的主要内容,如果未能解决你的问题,请参考以下文章

统计数组中的字符C语言解法——剑指 Offer 50. 第一个只出现一次的字符

统计数组中的字符C语言解法——剑指 Offer 50. 第一个只出现一次的字符

统计数组中的字符C语言解法——剑指 Offer 50. 第一个只出现一次的字符

力扣剑指off 56-I数组中数字出现次数

《剑指Offer——数组中只出现一次的两个数字,数组中唯一只出现一次的数字》代码

剑指OFFER 数组中只出现一次的数字