数组中只出现一次的数字

题目描述

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

思路一

23

代码

public class Find {

    public static void main(String[] args){

        Find find = new Find();
        int[] arr = {2,4,3,6,3,2,5,5};
        int[] num1 = new int[1];
        int[] num2 = new int[1];
        find.FindNumsAppearOnce(arr,num1,num2);
        System.out.println(num1[0]);
        System.out.println(num2[0]);
    }

    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        if(array == null || array.length <= 1){
            num1[0] = num2[0] = 0;
            return;
        }

        //整个数组从头两两异或,最终的结果必然是两个不同数字的异或结果
        //因为相同的数字两两异或之后为0
        //0和任意一个数异或还是这个数本身
        int len = array.length;
        int sum = 0;
        for(int i = 0; i < len; i++){
            sum ^= array[i];
        }


        int index = 0;
        //java中int类型占4个字节,即32个bit
        //从左开始找到这个异或结果第一个为1的索引(寻找两个特殊数的二进制数的第一个不同的位所在的位置)
        while((sum&1) == 0 && index < 32){
            sum = sum >> 1;
            index++;
        }

        //以这个索引处是否为1作为判定标准,就将两个不同的数分离开了
        //下面就是分两批不停地异或,就会得到这两个不同的数
        for(int i = 0; i < len; i++){
            //这样就可以分别找到index处为1的独特解以及为0的独特解
            if(isBit(array[i],index)){
                num1[0] ^= array[i];
            }else{
                num2[0] ^= array[i];
            }
        }
    }

    //判断num的倒数第index位是否为1
    private boolean isBit(int num,int index){
        //先将num向右移index位        
        num = num >> index;
        //判断倒数第index位是否为1
        if((num & 1) == 1){
            return true;
        }else{
            return false;
        }
    }
}

思路二

利用hashset的不可重复性

import java.util.HashSet;

public class Finde {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        HashSet<Integer> set = new HashSet<Integer>();

        for (int i = 0;i < array.length;i++){
            /**
             * Adds the specified element to this set if it is not already present.
             * If this set already contains the element, the call leaves the set
             * unchanged and returns <tt>false</tt>.
             */
            boolean flg = set.add(array[i]);
            if(!flg){
                //如果set中已经存在,说明该数字出现了两次那么就删除该数字
                set.remove(array[i]);
            }
        }

        Object[] temp =set.toArray();
        num1[0] = (int) temp[0];
        num2[0] = (int) temp[1];
    }
}

原文地址:https://www.cnblogs.com/flyingcr/p/10698540.html