剑指offer31

98 阅读1分钟

题目描述

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

解题思路分析

  • 首先我们得知道,两个相同的数异或为0,任何数与0异或是本身
  • 知道上面那个之后,我们可以先让数组中的每个数字依次进行异或运算,最后得到的结果就是这两个只出现一次的数的异或结果n
  • 根据上面求得的异或结果n我们可以知道,n从右往左数第一个1的位置就是这两个数第一个不同的位置,我们找出第一个1的位置,在这个位置上,对于这两个只出现了一次的数来说,他们一个为0一个为1,根据这个我们可以把数组中的数字分为两类,一类是该位置上为1,另一类则是该位置上为0,然后依次异或这两类,就可以得出这两个只出现了一次的数了

代码实现

public void findNumsAppearOnce(int[] nums, int[] num1, int[] num2) {
    if (nums == null || nums.length <= 0) {
        return;
    }
    int length = nums.length;
    int temp = 0;
    for (int i = 0; i < length; i++) {
        temp ^= nums[i];
    }
    int index = findFirst1(temp);
    for (int i = 0; i < length; i++) {
        //开始根据index位置上是否是1开始分类,然后异或下去就好了
        if (isBit(index, nums[i])) {
            num1[0] ^= nums[i];
        } else {
            num2[0] ^= nums[i];
        }
    }
}
//找到第一次出现1的地方,很简单,跟着代码就能看懂
private int findFirst1(int num) {
    int index = 0;
    while ((num & 1) == 0 && (index < 32)) {
        index++;
        num >>= 1;
    }
    return index;
}
//判断num在index位置上是否为1
private boolean isBit(int index, int num) {
    num >>= index;
    return num & 1 != 0;
}