java 一个整形数组中除了两个数字只出现一次外,其它的数字都出现了两次,获取这两个数字

问题描述:一个整形数组中除了两个数字只出现一次外,其它的数字都出现了两次,获取这两个数字。

思路1:
1) 任何一个数字和自己本身做异或操作的结果都为0,任何一个数字和0做异或操作的结果都为数字本身。
2) 将所有的元素一起做异或操作
3) 异或操作的结果的二进制表示中,按照从右往左的顺序,找到第一个1出现的位置x
4 )将数组中的元素分为两类:
1> 第一类:从右边开始数第x位上的数字为1的元素
2> 第二类:从右边开始数第x位上的数字为0的元素
5)分别对两类元素做异或操作,异或操作的结果即只出现一次的两个元素。

   /**
     * 一个整形数组,除了两个数字只出现一次以外,其他都出现了两次,找到这两个数字
     * @param array
     * @return
     */
    public static int[] findNumApperOnce(int[] array) {
        int tmp = 0;
        for(int i = 0;i < array.length;i++) {
            tmp ^= array[i]; //得到的是数组中那两个不同元素异或的结果
        }

        int x = 0;
        //判断两个数异或结果的二进制数从右往左数第几位是1
        while((tmp & 1) == 0 && x <= 32) {  
            tmp >>= 1;
            x++;
        }

        int a = 0,b = 0;
        for(int i = 0;i < array.length;i++) {
            if(isOne(array[i],x)) {
                a ^= array[i]; //将二进制数从右往左数的第x位为1的一组数异或,得到一个结果
            }else {
                b ^= array[i];  //将二进制数从右往左数的第x位为0的一组数异或,得到一个结果
            }
        }
        return new int[] {a,b}; //返回的这两个数,就是数组中两个只出现一次的元素

    }


    /**
     * 判断当前数组元素的第index位是否为0
     * @param number
     * @param index
     * @return
     */
    public static boolean isOne(int number,int index) {
        number = number >> index;
        if((number & 1) != 0) {
            return true;
        }else {
            return false;
        }
    }

思路2:
1)定义一HashMap的集合(键表示出现的数字,值表示数字出现的次数),遍历数组,一次往集合中添加元素,记录出现次数。
2)定义一个ArrayList集合,遍历HashMap集合,把只出现一次的元素添加到ArrayList集合中
3)遍历读取ArrayList集合即可(数组中只出现一次的元素有0~n个,都可以拿这种方法)

   /**
     * 一个整形数组,除了两个数字只出现一次以外,其他都出现了两次,找到这两个数字
     * @param array
     * @return
     */
    public static int[] findNumber(int[] array) {
        Map<Integer,Integer> hashMap = new HashMap<>();
        for(int i = 0;i < array.length;i++) {
            if(! hashMap.containsKey(array[i])) {  
                hashMap.put(array[i],1);  //第一次添加,每个元素都只出现一次
            }else {
                hashMap.put(array[i],hashMap.get(array[i])+1); //后面添加再遇到这个元素,出现次数+1
            }
        }

        ArrayList<Integer> arrayList = new ArrayList<>();

        Iterator<Map.Entry<Integer,Integer>> iterator = hashMap.entrySet().iterator();
        while(iterator.hasNext()) {
            Map.Entry<Integer,Integer> next = iterator.next();
            Integer key = next.getKey();
            Integer value = next.getValue();
            if(value == 1) {  //元素只出现一次
               arrayList.add(key);
            }
        }

        Iterator<Integer> iterator1 = arrayList.iterator();
        int[] array1 = new int[2];
        int i = 0;
        while(iterator1.hasNext()) {
            Integer next = iterator1.next();
            array1[i] = next;
            i++;
        }

        return array1;
    }

这个题的简单变种是:一组数据中,只有一个元素出现了一次,其他元素均出现了偶数次

思路

  1. 任何一个数字和自己本身做异或操作的结果都为0,任何一个数字和0做异或操作的结果都为数字本身。
  2. 将所有的元素一起做异或操作,得到的结果就是那个只出现一次的元素
   /**
     * 一组数据中,只有一个元素出现了一次,其他元素均出现了偶数次,找到这个元素
     * @param array
     * @return
     */
    public static int[] findNumber1(int[] array) {
        if(array == null || array.length == 0) {
            return null;
        }
        int tmp = 0;
        for(int i = 0;i < array.length;i++) {
            tmp ^= array[i];
        }
        return tmp;
    }

猜你喜欢

转载自blog.csdn.net/QQ2899349953/article/details/83190384