1. 程式人生 > >尋找陣列中只出現一次的數 java實現

尋找陣列中只出現一次的數 java實現

最近在複習演算法,準備面試。在網上看到一個很有意思的面試題,瞭解了演算法思想之後自己用java語言實現了一下。這個面試題主要考察的是位操作的基礎。這篇文章在思路上借鑑了http://blog.csdn.net/morewindows/article/details/12684497這篇文章,也借鑑了其中的一些講解,一方面是為了自己以後複習看,另一方面也可以提供給他人作為參考。另外就是自己試著用java實現了文中的演算法思路,並附上了程式碼。

首先看看題目要求:

陣列A中,除了某一個數字x之外,其他數字都出現了三次,而x出現了一次。請給出最快的方法找到x

如果陣列中沒有x,那麼陣列中所有的數字都出現了3次,在二進位制上,每位上1的個數肯定也能被3整除。如{1, 5, 1, 5, 1, 5}從二進位制上看有:

1:0001

5:0101

1:0001

5:0101

1:0001

5:0101

二進位制第0位上有6個1,第2位上有3個1.第1位和第3位上都是0個1,每一位上的統計結果都可以被3整除。而再對該陣列新增任何一個數,如果這個數在二進位制的某位上為1都將導致該位上1的個數不能被3整除。因此通過統計二進位制上每位1的個數就可以推斷出x在該位置上是0還是1了,這樣就能計算出x了。

推廣一下,所有其他數字出現N(N>=2)次,而一個數字出現1次都可以用這種解法來推匯出這個出現1次的數字。

示範程式碼如下:

/*
 * 陣列A中,除了某一個數字x之外,其他數字都出現了3次,而x出現了一次。請給出最快的方法找到x。
 */
public class FindNum {
	
	public static int findNum(int a[])
	{
		int result = 0;
		
		int bits[] = new int[32];
		for(int i = 0; i < a.length; i++)
		{
			for(int j = 0; j < 32; j++)
			{
				bits[j] += ((a[i] >> j) & 1);
			}
		}
		
		for(int j = 0; j < 32; j++)
		{
			if(bits[j] % 3 != 0)
			{
				result = result + (1 << j);
			}
		}
		
		return result;
	}
	
	public static void main(String[] args) {
		int a[] = {2, 3, 1, 2, 3, 5, 1, 2, 3, 1, 4, 4, 4}; 
		System.out.println(findNum(a));
	}
}