【Offer】[56-1] 【数组中只出现一次的两个数字】

题目描述

  一个整型数组里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是0(1)。

牛客网刷题地址

思路分析

  1. 如果将此题改为只有一个数字出现过一次,其他数字出现两次,那么,我们就可以用异或的方式,将所有数字进行异或,最终得到的结果就为只出现过一次的数字,因为重复的数字 异或运算便会各自抵消掉;
  2. 我们可以讲数组分为两组,每一组符合上面的条件,分组的方式如下:
  3. 把所有的数字异或之后得到 resultExcuOR,这个异或的结果二进制中至少有一位是1,我们找出第一个为1的位置,记为n位;以数字的第n位是否为1为标准,将数组进行分组,分组得到结果符合1中条件;

测试用例

  1. 功能测试:数组中有多对重复的数字;数组中没有重复的数字。

Java代码

public class Offer056_01 {
    public static void main(String[] args) {
        test1();
        test2();
        test3();

    }

    public static void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {
        Solution1(array,num1,num2);
    }

    

    private static void Solution1(int[] array, int[] num1, int[] num2) {
        if(array==null || array.length<2){
            return;
        }
        int resultExcuOR = 0;
        for(int i=0;i<array.length;i++){
            resultExcuOR ^= array[i];
        }
        int indexOf1 = 0;
        while( ((resultExcuOR&1)==0) && indexOf1<=4*8){ 
            resultExcuOR = resultExcuOR>>1;
            indexOf1++;
        }
        
        num1[0]=0;
        num2[0]=0;
        for(int i=0;i<array.length;i++){
            if(isBit1(array[i],indexOf1)){
                num1[0] ^= array[i];
            }else{
                num2[0] ^= array[i];
            }
        }
    }

    private static boolean isBit1(int num, int indexOf1) {
        num = num>>indexOf1;
        return (num&1)==1;
    }
    
    private static void test1() {

    }
    private static void test2() {

    }

    private static void test3() {

    }

}

代码链接

剑指Offer代码-Java