题目:算法
一个整型数组里除了两个数字以外,其余的数字都出现了两次。请写程序找出这两个只出现一次的数字。数组
看题目脑子里就出现作法了:spa
遍历,用个HashMap来记录出现的次数,而后再遍历HashMap返回的EntrySet找出出现一次的数字搞定。code
代码顺便上下吧:blog
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) { HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); Integer count; for(int temp : array) { if( (count = map.get(temp)) == null )map.put(temp, 1); else map.put(temp, ++count); } num1[0] = -1;num2[0] = -1; Set<Entry<Integer, Integer>> entrySet = map.entrySet(); for(Entry<Integer, Integer> temp : entrySet) { if( (count = temp.getValue()) == 1 && num1[0] == -1)num1[0] = temp.getKey(); else if(count == 1)num2[0] = temp.getKey(); } }
而后看牛客网的讨论,原来能够用异或操做很帅气地解决这个问题哈哈,来记录一下。get
基础知识:it
思路:(来自牛客的一个小伙子)io
而后上一下我本身根据这个思路写的代码,已经经过:class
/*高端的位运算法*/ public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) { int firstXorResult = 0;//0和任何数异或都为自己 for(int temp : array) { firstXorResult ^= temp;//异或知足结合率,a^b^a = b } //这样获得的firstXorResult就是惟一两个只出现一次的数字的亦或结果,也就是这个firstXorResult中为1的地方,就是这两个数字在位上面不一样的地方 int shiftBit = 0; while(shiftBit <= 31) {//这个循环是看从最低位开始,哪一个位是第一个不一样的,也就是为1的 if( (firstXorResult & (1 << shiftBit)) != 0 )break; shiftBit++; } List<Integer> list1 = new ArrayList<Integer>(); List<Integer> list2 = new ArrayList<Integer>(); for(int temp : array) { //根据刚刚的shiftBit,把数字分红两份,一份相与为0,一份不为0。首先确定那两个只出现一次的数字确定分开的;而后相同的数字确定分到一个list if( (temp & (1 << shiftBit)) == 0 ) { list1.add(temp); } else { list2.add(temp); } } int result1 = 0, result2 = 0; for(int temp : list1) {//异或结束获得的就是结果 result1 ^= temp; } for(int temp : list2) { result2 ^= temp; } num1[0] = result1; num2[0] = result2; }