剑指offer:数组中只出现一次的两个数(java)

/**
 * 题目:
 *      一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
 *解题思路:
 *      首先将整个数组的元素依次相与,然后找到相与结果中1第一次出现在哪一位,(比如是第n位)
 *      然后根据第n位是1或者不是1将数组分成两个子数组,然后分别将两个子数组中的元素相与,
 *      便会分别得到两个在数组中只出现一次的数字。
 */
public class P275_FindNumsAppearOnce {
    public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {
        if (array.length == 2) {
            num1[0] = array[0];
            num2[0] = array[1];
        }

        //整个数组元素相异或,最后的结果是两个只出现一次数字相与的结果
        int bit = 0;
        for (int i = 0; i < array.length; i++) {
            bit ^= array[i];
        }

        //确定相与结果的第一个1出现在哪一位

        int index1 = FindFirst1(bit);

        num1[0] = 0;
        num2[0] = 0;
        //将数组分成两个子数组,一个子数组是第index1位是1,另一个子数组树第index位是0
        for (int i = 0; i < array.length; i++) {
            if (IsBit1(array[i], index1)) {
                num1[0] ^= array[i];
            } else num2[0] ^= array[i];
        }
    }

    public int FindFirst1(int num) {
        if (num == 0) {
            return 0;
        }

        int index = 0;
        while ((num & 1) != 1 && index < 32) {
            num = num >> 1;
            index++;
        }
        return index;
    }

    public boolean IsBit1(int num, int index) {
        for (int i = 0; i < index; i++) {
            num = num >> 1;
        }
        return (num & 1) == 1;
    }

    public static void main(String[] args) {
        int[] array = {2, 4, 3, 6, 3, 2, 5, 5};

        int[] num1 = new int[1];
        int[] num2 = new int[1];
        P275_FindNumsAppearOnce test = new P275_FindNumsAppearOnce();
        test.FindNumsAppearOnce(array, num1, num2);

    }
}

猜你喜欢

转载自blog.csdn.net/Sunshine_liang1/article/details/82873281