case1
一个整形数组中除了一个数字之外,其他数字都出现了两次,请找出这个数。要求时间复杂度O(n),空间复杂度O(1).
思路:
关键词:一次,两次。
出现两次会带来什么效果?联想到异或,一个数与自身异或结果为零。
解法:
将数组中所有的数异或起来,出现两次的数相互抵消,最后的结果就是只出现一次的数。
case2
一个整形数组中除了两个数字之外,其他数字都出现了两次,请找出这个数。要求时间复杂度O(n),空间复杂度O(1).
思路:
- 沿用上题思路,全都异或起来,结果是两个只出现的一次的数的异或结果。要分开,如何分开?
- 从异或入手,两数异或结果中为1的bit,就是两个数的二进制表示不同的位数,任意选一位来分割原数组,再分别异或即可。
- 不care其他数到底分在哪个组里,反正某两个相同的数会被在同一组中并抵消)
解法:
- 将数组中所有的数异或,得到result1
- 找出result1中第一个为1的bit(假设为n)
- 以bit n的情况划分原数组,两组内分别异或
源程序:
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int lengh = data.size();
int result = 0;
for(int i = 0;i < lengh;++ i)
result = result ^ data[i];
//分割数组的数
int partition = 1;
while (!(result & partition))
partition = partition << 1;
*num1 = 0;
*num2 = 0;
for(int i = 0;i < lengh;++ i) {
if (data[i] & partition)
*num1 = (*num1) ^ data[i];
else
*num2 = (*num2) ^ data[i];
}
}
};