题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路:
异或的性质:任何一个数字异或它自己都等于0。
将数组拆成2个子数组,每个子数组中分别只含有1个只出现一次的数字。
原问题变成2个子问题:
1如何在一个数组中,找出只出现 只出现1次的数字?---》从头到尾依次异或数组中的每一个数字,
最终的结果就是只出现一次的数字。
2如何划分数组?---》从头到尾依次异或数组中的每一个数字,最终的结果是2个出现一次数字的异或。
这2个数字不一样,异或结果中至少有一位为1,我们在异或结果中找到第一个为1的位置,记为第n位。
我们以第n位是否为1来划分数组。
1 //num1,num2分别为长度为1的数组。传出参数 2 //将num1[0],num2[0]设置为返回结果 3 public class Solution { 4 public void FindNumsAppearOnce(int [] a,int num1[] , int num2[]) { 5 6 int bitResult = 0; 7 for(int i = 0;i<a.length;i++) 8 bitResult^=a[i]; 9 int index = findFirst1(bitResult); 10 for(int i=0;i<a.length;i++){ 11 if(bitIs1(a[i],index)){ 12 num1[0]^=a[i]; 13 } 14 else{ 15 num2[0]^=a[i]; 16 } 17 } 18 19 } 20 private int findFirst1(int bitResult){ 21 int bit_index = 0; 22 while((bitResult&1)==0&&bit_index<32){ 23 bitResult>>=1; 24 bit_index++; 25 } 26 return bit_index; 27 } 28 private boolean bitIs1(int target,int bit_index){ 29 //判断target(是个数字)二进制表示的时候是不是第n位为1 30 //右移n位 与1 与 31 return ((target>>bit_index)&1)==1; 32 33 } 34 }