文章目录
-
- 1.一个长度为n的数组,只有一个数字出现了一次,其余数字均出现了两次,请找到出现一次的这个数字
- 2.一个长度为n的数组,只有两个数字出现了一次,其余数字均出现了两次,请找到出现一次的这两个数字
- 3.在一个长度为n的数组里的所有数字都在0~n - 1范围内,已知只有一个数字出现了两次,其余数字出现了一次,如何找到这个出现两次的数字,分析时间复杂度.
- 4.在一个长度为n + 1的数组里的所有数字都在1~n范围内,已知只有一个数字出现了两次,其余数字出现了一次,如何找到这个出现两次的数字,不能修改输入的数组,分析时间复杂度.
- 5.(一个数出现n次,其他数出现m次,n < m)在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
1.一个长度为n的数组,只有一个数字出现了一次,其余数字均出现了两次,请找到出现一次的这个数字
异或运算的性质:1.结合律:a ^ b = b ^ a;
2.交换律:(a ^ b ) ^ c = a ^ (b ^ c);
两个相同的数抑或得到的数是0;任何数与0抑或得到的是它本身
故一个整型数组中,若只有一个数字只出现一次,其他数字都出现了两次,那么把数组中的所有的数遍历异或一遍的结果就是只出现一次的那个数字.
#include<iostream>
using namespace std;
int main() {
int n, sum = 0, temp;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> temp;
sum ^= temp;
}
cout << sum << endl;
return 0;
}
2.一个长度为n的数组,只有两个数字出现了一次,其余数字均出现了两次,请找到出现一次的这两个数字
思路
[a, b, c, c, d, d, e, e, f, f]
1.现将出现偶数的数通过异或去掉:
(1)两个相同的数异或的结果是0;
(2)所有不为0的数和0异或的结果是本身。
(a异或b=a’b+b’a),
2.异或后的数是要求的两个数(a和b)的异或结果
3.异或得到的数找到该数的二进制数是1的一个位置(ind), 该数是一意味着该位置上a和b是不一样的, 一个是1, 一个是0.这样我们可以将数组里的数分成两组, 一组数的二进制数在ind是1(a, c, c, f, f), 一组数在ind的值为0(b, d,d, e, e).在将两组数分别异或便可得a和b.
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
int main() {
int n;
cin >> n;
int nums[n + 5];
int add = 0;
for (int i = 0; i < n; i++) {
cin >> nums[i];
add ^= nums[i];
}
int left = 0;
for (int i = 0; i < 32; i++) {
if ((add >> i) & 1) {
left = i;
break;
}
}
int num1 = 0, num2 = 0;
for (int i = 0; i < n; i++) {
if ((nums[i] >> left) & 1) {
num1 ^= nums[i];
} else {
num2 ^= nums[i];
}
}
cout << num1 << " " << num2 << endl;
return 0;
}
3.在一个长度为n的数组里的所有数字都在0~n - 1范围内,已知只有一个数字出现了两次,其余数字出现了一次,如何找到这个出现两次的数字,分析时间复杂度.
时间复杂度: O ( n ) O(n)