題目
1-1000這1000個數放在含有1001個元素的數組中,只有唯一的一個元素重複,其它均只出現一次。每個數組元素只能訪問一次,設計一個算法,將它找出來;不用輔助空間,能否實現。
算法
1.不需要輔助空間
注:因爲知道不重複的其他數時哪些所以可以使用此方法,否則只能使用方法二
思路:
只有一個數是出現兩次的,聯想到 ^
異或運算中,兩個相同的數 異或
得到 0, 0
和任何一個數 異或
還等於這個數(即A^A=0,A^0=A)
設題目中的數組爲 arr
, 讓 arr
與1-1000共1000個數 異或
, 這樣除了 arr
中重複了兩次那個數得到保留外,其它的數均變爲0,輸出這個數即可
2.需要輔助空間
使用一個1001個元素的數組helper,helper[i]
記錄數字 [i]
出現的次數,helper[i]==2
的 i
即爲要找的數
代碼如下:
package 位運算;
import jdk.jshell.execution.Util;
import java.util.Random;
import java.util.*;
public class wei {
public static void swap(int [] a,int x,int y)
{
int temp;
temp=a[x];
a[x]=a[y];
a[y]=temp;
}
public static void main(String[] args)
{
int N=1001;
int [] arr=new int[N];
for(int i=0;i<arr.length-1;i++)
{
arr[i]=i+1;
}
//最後一個數是隨機數
arr[arr.length-1]=new Random().nextInt(N-1)+1;//nextInt函數作用:該方法的作用是生成一個隨機的int值,該值介於[0,n)的區間,隨機int值在包含0而不包含n區間內。
//隨即下標
int Index=new Random().nextInt(N);
//交換最後一個下標上的數到隨機下標位置
swap(arr,Index,arr.length-1);
System.out.println(Arrays.toString(arr));//打印數組的方法
System.out.println("====不建立輔助空間====");
//異或消除重複
int x1=0;
for(int i=1;i<=N-1;i++)
{
x1=(x1^i);//1-1000個數異或
}
for(int i=0;i<N;i++)
{
x1=x1^arr[i];//1-1000個數再與arr中的數異或,得出重複的數
}
System.out.println(x1);
System.out.println("======建立輔助空間的方法=====");
//利用輔助數組的下標代表出現的次數
int[ ] helper=new int[N];
for(int i=0;i<N;i++)
{
helper[arr[i]]++;
}
for(int i=0;i<N;i++)
{
if(helper[i]==2)
{System.out.println(i);
break;}
}
}
}
運行結果: