重複的數:
題目描述:1到1000這1000個數放在含有1001個元素的數組中,只有唯一的一個元素值重複,其他均只出現一次,找出這個重複的值。
解法1:巧妙使用位運算
public static void main(String[] args) {
int N = 11;
int[] a = new int[N];
//初始化數組 不包括最後一個元素
for (int i = 0; i < a.length - 1; i++) {
a[i] = i + 1;
}
//數組的最後一個元素是隨機數 就是和前面重複的那個數k 模擬這個重複的數字出現在末尾 實際不一定 但是對於算法不影響
a[a.length - 1] = new Random().nextInt(N - 1) + 1;
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(); //打出換行
int x = 0;
for (int i = 1; i < N ; i++) {
x = (x ^ i);
}
for (int i = 0; i < N; i++) {
x = x ^ a[i];
}
System.out.println(x);
}
}
解析:上述算法等價於:1
解法2:使用輔助數組
public static void main(String[] args) {
int N = 11;
int[] a = new int[N];
//初始化數組 不包括最後一個元素
for (int i = 0; i < a.length - 1; i++) {
a[i] = i + 1;
}
//數組的最後一個元素是隨機數 就是和前面重複的那個數k 模擬這個重複的數字出現在末尾 實際不一定 但是對於算法不影響
a[a.length - 1] = new Random().nextInt(N - 1) + 1;
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(); //打出換行
// 開闢一個輔助數組空間 每一個數組元素存儲的是 原來數組中對應的元素出現的次數 有點像桶排序的計數器
int[] helper=new int[N];
for(int i=0;i<N;i++){
helper[a[i]]++;
}
for(int i=0;i<N;i++){
if(helper[i]==2){
System.out.println(i);
break;
}
}
}
}
總結:
第一種解法的感悟 :此種解法就是要構造K,使其出現次數爲奇數次,其餘的數據出現次數都是偶素次,
那麼連續的疑惑操作之後,偶數次出現的數據都沒了,剩下的就是奇數次出現的數據K 但是侷限於數據必須連續
第二種解法的感悟:以空間換時間 如果原數據中出現了很大的數據 那麼就必須要構造一個很大的輔助數組 但是這種方法適合通用 不必要求數據連續性
落單的數:
題目描述:某一個數組裏面只有一個數K出現了一次,其餘的都出現了2次,找出這個數。
public static void main(String[] args) {
int[] a=new int[]{1,1,2,2,3,3,4,4,5,5,6,7,7,8,8,9,9,0,0};
int x=0;
for(int i=0;i<a.length;i++){
x=x^a[i];
}
System.out.println(x);
}
//解析:所有出現偶數次的數據 都會在連續的異或之後消掉,只剩下出現奇數次的數據