版权声明:本博客可任意转载,不用通知 https://blog.csdn.net/hbkzhu13579/article/details/84581666
链接
牛客:数组中只出现一次的数字
题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
思路
参考:数组中只出现一次的数
我们从头到位对数组做异或运算,得到的最终结果应该是两个不同数字做异或运算后的值。因为两个数字不相同,最终的结果也肯定不是0,切结果对应的二进制位中至少有一个为1,我们找到二进制位中第一个是1的位置,即为n,然后根据地n为是1还是0把数组分为两个子数组,第一个子数组中的每个数的二进制位的第n位都是1,另外一个是0,这样分完后,相同的数字肯定会被分到同一个子数组中,并且每个子数组中只包含一个只出现一次的数,根据问题一,我们可以很方便的求出两个只出现一次的数.
代码
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
//找到从右向左第一个位为1的下标indexBit
public static int FindFirstBit(int num){
int indexBit = 0;
while((num & 1) == 0){
num = num >> 1;
indexBit++;
}
return indexBit;
}
//找到第indexBit位是否为1
public static int isBit1(int num,int indexBit){
num = num >> indexBit;
return (num & 1);
}
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public static void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int len = array.length;
if(array == null && len < 2)
return;
int resultOr = 0;
//偶数次出现的数字异或结果都为0 所以resultOr就是两个只出现一次的不相等的数字异或的结果
for(int i = 0; i < len; i++){
resultOr ^= array[i];
}
//根据上面问题一的思路,我们依然从头到位对数组做异或运算,
//得到的最终结果应该是两个不同数字做异或运算后的值。因为两个数字不相同,
//最终的结果也肯定不是0,切结果对应的二进制位中至少有一个为1,我们找到二进制位中第一个是1的位置,
//即为n,然后根据地n为是1还是0把数组分为两个子数组,第一个子数组中的每个数的二进制位的第n位都是1,
//另外一个是0,这样分完后,相同的数字肯定会被分到同一个子数组中,
//并且每个子数组中只包含一个只出现一次的数,根据问题一,我们可以很方便的求出两个只出现一次的数,
//实现如下:
int indexOf = FindFirstBit(resultOr);
num1[0] = num2[0] = 0;
for(int j = 0; j < len; j++){
if(isBit1(array[j], indexOf) == 1){
num1[0] ^= array[j];
}else{
num2[0] ^= array[j];
}
}
}
}