数组中只出现一次的数字

题目描述

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

第一想法

  • 排序,然后一对一对找O(N ^ 2)

看了讨论区

class Solution {
public:
    void FindNumsAppearOnce(vector data,int* num1,int *num2) {
        int num;
        for(int i = 0;i < data.size();++i){
            num = num ^ data[i];
        }
        int index = FindFisrt1(num);
        for(int i = 0;i < data.size();++i){
            if(IsBit(index, data[i])){
                *num1 ^= data[i];
            }
            else
                *num2 ^= data[i];
        }
    }
    
    int FindFisrt1(int num){
        int index = 0;
        while(!(num % 2)){
            num >>= 1;
            index++;
        }
        return index;
    }
    
    bool IsBit(int index, int num){
        return num >> index & 1 == 1;
    }
};

存在的问题

int num;
num ^= 1;
//------
num的值为1

为什么这么计算

思路

  • 在两两成对的数组中,找一个不成对的数.
    1.从同异或到尾,相同的数异或为0,剩余不成对的数异或为其本身.

  • 在两两成对的数组中,找两个不成对的数.
    1.从头异或到尾.得到的数为这两个不成对的数的异或(假定其值为a)
    2.在a中按二进制从后向前找到第一位为1的位(二进制下,假定其为index位),表示这一位可以区别这两个不成对的数
    3.遍历一遍数组,将index位为1的组进行异或,为0的进行异或(重复的数在同一数组中),两边异或的结果就是这两个不成对的数.

知识点

异或
  • 使用^表示(同或为! a^b)
  • 相同的数异或为0
  • 一个数与0异或为0

方法

  • 使用异或处理成对的数,找到单身狗.

你可能感兴趣的:(数组中只出现一次的数字)