剑指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;
说明:
- “ bitNums[31 - i] += num >> (31 - i) & 1”,判断每个数二进制数位是0或1,统计对应数位1的个数。
以上是关于剑指offer-004-只出现一次的数字的主要内容,如果未能解决你的问题,请参考以下文章
统计数组中的字符C语言解法——剑指 Offer 50. 第一个只出现一次的字符
统计数组中的字符C语言解法——剑指 Offer 50. 第一个只出现一次的字符
统计数组中的字符C语言解法——剑指 Offer 50. 第一个只出现一次的字符