一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
IDEA
1.用list,删除重复出现的元素,只留下出现一次的元素,但要注意list remove()函数的使用:按值删除,而非按键删除
2.异或运算^:二进制位异或,相同为0,不同为1。故有这样的性质两个相同的数字异或为0,一个数与0异或还是它本身。
该数组中只有两个数只出现一次,因此将该数组中所有元素异或,得到的是这两个数组的异或结果(其他出现两次的数相互低抵消)。
这个结果的二进制中的1,表现的这个两个数不同的位。我们就取这个结果的第一个1作为标志位,把原数组分成两组。这样可以将数组分为两组,一组在该标志位为1,一组在该标志位为0,这两个不同数字分别在这两组内。然后把这两个组按照最开始的思路,依次异或,剩余的两个结果就是这两个只出现一次的数字。
CODE
1.
//num1,num2分别为长度为1的数组。传出参数 //将num1[0],num2[0]设置为返回结果 import java.util.ArrayList; public class Solution { public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) { ArrayList<Integer> list=new ArrayList<Integer>(); for(int i=0;i<array.length;i++){ if(!list.contains(array[i])){ list.add(array[i]); }else{ list.remove(Integer.valueOf(array[i])); } } if(list.size()>1){ num1[0]=list.get(0); num2[0]=list.get(1); } } }
2.
public class Solution { public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) { int res=0;num1[0]=0;num2[0]=0; for(int i=0;i<array.length;i++){ res^=array[i]; } int index=0;//标志位,记录这个结果res中出现第一个1是位置,从低位开始 while((res&1)==0){ res>>=1;//右移一位 index++; } for(int i=0;i<array.length;i++){ if(((array[i]>>index)&1)==0){//标志位为0的一组 num1[0]^=array[i]; }else{//标志位为1的一组 num2[0]^=array[i]; } } } }