一组带数字编号的球里除了两个编号之外,其它的编号都出现了两次。
请写程序找出这两个只出现一次的编号。要求时间复杂度是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)); } }