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

题目描述

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

解题思路

先来个简单题,如果题目是这样子的:
一个整型数组里除了一个数字之外,其他的数字都出现了偶数次。请写程序找出这一个只出现一次的数字。
这个题就so easy了。xor(异或)有个重要的性质:
任何数字异或它自己都等于0(异或,一种位运算,相同为0,不同为1)
用0异或整个数字,结果就是只出现一次或者只出现奇数次的数字(因为偶数次的数字在异或运算中都抵消了)。

现在的问题是有两个出现次数为一次的数字。那么只要把数组分成两部分,每一部分分别含有一个出现次数为1(或者奇数次也可以的)的数字就可以了。

先用0对整个数字进行异或运算,结果为xor,是两个只出现一次的数字的异或的结果。出现次数为1的两个数字肯定不相同,那么xor中至少有一位为1。我们在xor中找到第一位为1的位置,记为n。根据第n为是不是1可以把整个数组分为两部分。每一部分都只含有一个出现次数为1的数字,然后剩余的数字都出现偶数次。

AC代码

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        if(array.length < 2) return;
        int xor = 0;
        int partion = 1;
        for(int i = 0;i < array.length;i++) xor ^= array[i];
        partion = xor & -xor; // xor 中从右往左第一次出现 1 的位置
        for(int i = 0;i < array.length;i++){
            if((partion & array[i]) == 0) num1[0] ^= array[i];
            else num2[0] ^= array[i];
        }
    }
}

你可能感兴趣的:(算法)