一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
这道题呢在leetcode上见过,那道题是从1连续到n,中间缺了一个数,让你找出来缺的那个数是什么。这两道题很相似,那道题就是用了疑惑,数组中的每个数和从1开始的i抑或,这样剩下来的也就是单独出现的i,也就是数组中缺少的那个元素。
讲真,我看到这道题的时候完全没有想到用异或,而且得知是两个不一样的元素的时候也不知道怎么样去用异或。所以所算法,对于一般人来讲,就是见过,用的熟练的问题,不求你会发明创造,只要用的好就可以了。
扯远了,回到这道题上。这道题有两个单独出现的元素。如果使用异或走一遍这个数组的话得到的结果是非0的,也就是这两个元素异或的结果。那么根据这个结果,怎么找出这两个元素呢。
思考一下,两个不一样的元素的异或的结果肯定不是0。那么我们就找这个结果中有右往左第一个非0位,也就是1出现的第一次的位置。这两个元素中肯定有一个在这个位置是0,另一个在这个位置是1。而其他成对出现的元素也会分为两个部分,一个部分在个位置是1,另一个部分在这个位置是0.所以,我们就把一个数组求两个单独元素的问题就分割成,两个数组每个数组求其单独元素的问题。所以这个时候使用异或就很好解决了。
代码如下:
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
if(data.size() <2)return;
int hxor =0;
int flag =1;
for(int i=0;i<data.size();++i)
hxor ^= data[i];
while((hxor&flag)==0) flag <<= 1;
*num1 = hxor;
*num2 = hxor;
for(int i=0;i<data.size();++i)
{
if(data[i] & flag)
*num1 ^= data[i];
else
*num2 ^= data[i];
}
}
};
网友评论