题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
异或操作找数字, 学习了, 另外注意一下num << 1
左移一位, num数字本身并不改变, num = num << 1
此时num数字才被改变, 这坑跳了好多次了
思路: 当一个数字中除了一个数字出现一次外, 其他数字全部出现偶数次, 则把这个数组进行异或操作, 偶数次的数字异或全部为0, 剩下的则为那个出现一次的数字
同理, 当有两个出现一次的数字时, 异或的结果肯定有一位是1(否则就相同的), 通过这个位把数组区分为两个数组, 则可以把这两个不同数字划归到不同数组中, 剩下操作同上
class Solution {
public:
unsigned int findFirstBitIs1(int num) {
unsigned int counts = 0;
//while (1 != (num & 1)) {
while (((num & 1) == 0) && (num < 8 * sizeof(int))) {
counts++;
num = num >> 1;
}
return counts;
}
bool isBit1(int num, unsigned int index) {
num = num >> index;
return (num&1);
}
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
if (data.empty() || data.size() < 2)
return;
// 数组异或的结果
int res = 0;
for (int i = 0; i < data.size(); i++) {
res ^= data[i];
}
unsigned int firstBitIs1 = findFirstBitIs1(res);
*num1 = *num2 = 0;
for (int i = 0; i < data.size(); i++) {
if (isBit1(data[i], firstBitIs1)) {
*num1 ^= data[i];
}
else {
*num2 ^= data[i];
}
}
return;
}
};
利用STL库map建立映射, 没什么好说的
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
map<int, int> my_Map;
vector<int> vt;
for (int i = 0; i < data.size(); i++) {
my_Map[data[i]]++;
}
for (int i = 0; i < data.size(); i++) {
if (my_Map[data[i]] == 1) {
vt.push_back(data[i]);
}
}
*num1 = vt[0];
*num2 = vt[1];
return;
}
};