一组带数字编号的球里除了两个编号之外,其它的编号都出现了两次。
请写程序找出这两个只出现一次的编号。要求时间复杂度是O(n),空间复杂度是O(1)。
整形数组
长度不超过1000000
输出数组中2个只出现了一次的数
先输出较小的数
1 2 3 4 5 2 3 4 5 6
1 6
可以考虑以以下代码作为模板,实现其中的getNumber()函数。
#include <bits/stdc++.h>
using namespace std;
int a[1000001];
void getNumber(const int a[], int n, int&num1, int&num2) {
//自行实现,要求时间O(n),空间O(1)。
}
int main(void) {
int n = 0;
while (~scanf("%d",&a[n+1])) ++n;
int p,q;
getNumber(a,n,p,q);
if (p>q) swap(p,q);
printf("%d %d\n",p,q);
return 0;
}
/*
异或运算
出现两次的数异或为0,所有值异或等于两个只出现一次数的异或;
找到一个异或为1的位置t ,
位置t所有为0的值异或,所有为1的值异或,即为所求
*/
#include <bits/stdc++.h>
using namespace std;
int a[1000001];
void getNumber(const int a[], int n, int&num1, int&num2)
{
int i, yh = 0, t = 0;
for(i = 1; i <= n; i++) {
yh ^= a[i];
}
while((yh & 1) == 0) {
t++;
yh = yh >> 1;
}
num1 = 0;
num2 = 0;
for(i = 1; i <= n; i++) {
if((a[i] >> t) & 1) num1 ^= a[i];
else num2 ^= a[i];
}
}
int main(void)
{
int n = 0;
while (~scanf("%d", &a[n + 1])) ++n;
int p, q;
getNumber(a, n, p, q);
if (p > q) swap(p, q);
printf("%d %d\n", p, q);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main(){
int a[1000003],n=0,x=0,y=0,s=0,t=0;
while(cin>>a[n]){
s ^= a[n];
n++;
}
while((s&1)==0){
t++;
s >>= 1;
}
for(int i=0;i<n;i++){
if((a[i]>>t)&1)
x ^= a[i];
else
y ^= a[i];
}
cout<<min(x,y)<<" "<<max(x,y)<<endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int a[1000001];
void getNumber(const int a[], int n, int& num1, int& num2) {
//自行实现,要求时间O(n),空间O(1)。
int res = 0;
for (int i = 1; i <= n; ++i) {
res ^= a[i];
}
// 以flg作为分隔两个出现一次数字的标记
int flg = 1;
while ((res & 1) == 0) {
res >>= 1;
flg <<= 1;
}
for (int i = 1; i <= n; ++i) {
if (a[i] & flg) { // 分组
num1 ^= a[i];
} else {
num2 ^= a[i];
}
}
}
int main(void) {
int n = 0;
while (~scanf("%d", &a[n + 1])) ++n;
int p, q;
getNumber(a, n, p, q);
if (p > q) swap(p, q);
printf("%d %d\n", p, q);
return 0;
}
/*
data = []
while(1):
try:
data.append(int(input()))
except:
break
cur = 0
for i in data:
cur = cur^i
base = 1
while(base&cur)==0:
base*=2;
cur1,cur2=0,0
for i in data:
if i&base==0:
cur1 = cur1^i
else:
cur2 = cur2^i
print(min(cur1,cur2),max(cur1,cur2))
*/
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<unsigned>data;
unsigned tmp;
while(cin>>tmp)
{
data.push_back(tmp);
}
unsigned res_two = 0;
for(auto c:data)res_two^=c;
unsigned cur = 1;
while((res_two & cur)==0)
cur*=2;
unsigned res1=0,res2=0;
for(auto c:data)
{
if((c & cur))
res1^=c;
else
res2^=c;
}
cout<<min(res1,res2)<<" "<<max(res1,res2)<<endl;
} def getNumber(nums): t = 0 for i in nums: t = t ^ i index = 0 a, b = 0, 0 while (t & 1) == 0: t = t >> 1 index += 1 for i in nums: if ((i >> index) & 1) == 1: a = a ^ i else: b = b ^ i return a, b if __name__ == "__main__": arr = [] while True: try: arr.append(int(input())) except: break a, b = getNumber(arr) if a < b: print(a, b) else: print(b ,a)
#include <iostream>
#include <vector>
using namespace std;
int main(void){
int x, hash = 0, tag = 1, a = 0, b = 0;
vector<int> v;
while(cin>>x){
v.push_back(x);
hash ^= x;
}
while(!(hash & 1)){
tag <<= 1;
hash >>= 1;
}
for(int y : v){
if(y & tag)
a ^= y;
else
b ^= y;
}
if(a < b)
cout<<a<<' '<<b<<endl;
else
cout<<b<<' '<<a<<endl;
return 0;
} 所以数全部异或得到hash,hash中数位上为1表示这个数位上的a,b是不相同的,根据这个为判断将所有的数分为两类,相同的数肯定在同一类中,类中数再全部异或得到a,b的值arr = [] while True: tmp = input() try: tmp = int(tmp) arr.append(int(tmp)) except: break def isbit1(num, idx): num = num>>idx return num & 1 def findfirstbit(num): indexbit = 0 while(num & 1==0): num=num>>1 indexbit+=1 return indexbit i = 0 for k in arr: i = i^k a,b,idx = 0,0,findfirstbit(i) for i in arr: if isbit1(i,idx): a = a^i else: b = b^i print(a,b)
//开始用HashSet没通过,后来发现是Scanner的问题
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String temp;
int cur;
Set<Integer> set = new HashSet<>();
while((temp=br.readLine())!=null){
cur = Integer.parseInt(temp);
if(set.contains(cur)){
set.remove(cur);
}else{
set.add(cur);
}
}
Iterator it = set.iterator();
int a = (int) it.next();
int b = (int) it.next();
System.out.println(Math.min(a, b)+" "+Math.max(a,b));
}
}