40 数组中只出现一次的数字

Posted shareidea94

tags:

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

 题目要求:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

 

首先:位运算中异或的性质:两个相同数字异或=0一个数和0异或还是它本身

只有一个数出现一次时,我们把数组中所有的数,依次异或运算,最后剩下的就是落单的数,因为成对儿出现的都抵消了。

依照这个思路,我们来看两个数(我们假设是AB)出现一次的数组。我们首先还是先异或,剩下的数字肯定是A、B异或的结果,这个结果的二进制中的1,表现的是A和B的不同的位。我们就取第一个1所在的位数,假设是第3位,接着把原数组分成两组,分组标准是第3位是否为1。如此,相同的数肯定在一个组,因为相同数字所有位都相同,而不同的数,肯定不在一组。然后把这两个组按照最开始的思路,依次异或,剩余的两个结果就是这两个只出现一次的数字。
 
 1 //num1,num2分别为长度为1的数组。传出参数
 2 //将num1[0],num2[0]设置为返回结果
 3 public class Solution 
 4     public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) 
 5         //考虑特殊情况
 6         if(array == null || array.length <= 1)
 7             num1[0] = num2[0] = 0;
 8             return;
 9         
10         int len = array.length;
11         //xor为首轮将所有元素异或的结果
12         //index为找到异或结果中,低位首个为1的位bit
13         int index = 0; int xor = 0;
14         for(int i = 0; i < len; i++)
15             xor ^= array[i];
16         
17         //找到低位的1,就退出for,用break
18         for(index = 0; index < 32; index++)
19             if((xor & (1 << index)) != 0) break;
20         
21         for(int i = 0; i < len; i++)
22             if((array[i] & (1 << index))!=0)//与低位1,不同
23                 num2[0] ^= array[i];
24             else //与低位1,相同
25                 num1[0] ^= array[i];
26             
27         
28     
29 

有额外时间的话,也可以看看下面的代码


组中有两个出现一次的数字,其他数字都出现两次,找出这两个数字,这个解法这个中,基本也是按剑指offer中思路来的。第二个for()的意思是:sum的二进制表示中,1的位数,表示的是两个唯一数字二进制表示中不同的位,我们就找出第一个1所在的位数(index),在第三个for()循环中按照这个位将数组分成两个子数组,分组标准是数字在这个位上的值是否为1(此时数字相同的各位也相同,在同一个组中;不同数字,也就不在同一组里)。之后按照异或分别找出那两个唯一数即可。

 1 链接:https://www.nowcoder.com/questionTerminal/e02fdb54d7524710a7d664d082bb7811
 2 来源:牛客网
 3 
 4 /**
 5      * 数组a中只有一个数出现一次,其他数字都出现了3次,找出这个数字
 6      * @param a
 7      * @return
 8      */
 9     public static int find1From3(int[] a)
10         int[] bits = new int[32];
11         int len = a.length;
12         for(int i = 0; i < len; i++)
13             for(int j = 0; j < 32; j++)
14                 bits[j] = bits[j] + ( (a[i]>>>j) & 1);
15             
16         
17         int res = 0;
18         for(int i = 0; i < 32; i++)
19             if(bits[i] % 3 !=0)
20                 res = res | (1 << i);
21             
22         
23         return res;
24     

 

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

40 数组中只出现一次的数字

面试题40:数组中只出现一次的数字

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

[剑指offer] 40. 数组中只出现一次的数字

《剑指offer》:[40]数组中只出现一次的数字

剑指offer 40.知识迁移能力 数组中只出现一次的数字