1. 程式人生 > >【Java】 劍指offer(56-2) 陣列中唯一隻出現一次的數字 《劍指Offer》Java實現合集 56-1) 陣列中只出現一次的兩個數字 《劍指Offer》Java實現合集

【Java】 劍指offer(56-2) 陣列中唯一隻出現一次的數字 《劍指Offer》Java實現合集 56-1) 陣列中只出現一次的兩個數字 《劍指Offer》Java實現合集

 

本文參考自《劍指offer》一書,程式碼採用Java語言。

更多:《劍指Offer》Java實現合集  

題目

  在一個數組中除了一個數字只出現一次之外,其他數字都出現了三次。請找出那個只出現一次的數字。

思路

  這道題中數字出現了三次,無法像56-1) 陣列中只出現一次的兩個數字一樣通過利用異或位運算進行消除相同個數字。但是仍然可以沿用位運算的思路。

  將所有數字的二進位制表示的對應位都加起來,如果某一位能被三整除,那麼只出現一次的數字在該位為0;反之,為1。

 

測試算例 

  1.功能測試(唯一出現的數字是0,正數,負數;重複出現的數字是0,正數,負數)

Java程式碼

//題目:在一個數組中除了一個數字只出現一次之外,其他數字都出現了三次。請
//找出那個只出現一次的數字。

public class NumberAppearingOnce {
	public static int findNumberAppearingOnce(int[] arr) {
		if(arr==null || arr.length<=0)
			throw new RuntimeException();
		int[] bitSum = new int[32];
		for(int i=0;i<32;i++) 
			bitSum[i]=0;
		for(int i=0;i<arr.length;i++) {
			int bitMask=1;
			for(int j=31;j>=0;j--) {
				int bit=arr[i]&bitMask;  //注意arr[i]&bitMask不一定等於1或者0,有可能等於00010000
				if(bit!=0)
					bitSum[j]+=1;
				bitMask=bitMask<<1;
			}
		}
		int result=0;
		for(int i=0;i<32;i++) {
			result=result<<1;
			result+=(bitSum[i]%3);
			//result=result<<1;  //不能放在後面,否則最前面一位就沒了
		}
		return result;
	}
}

  

  

收穫

  1.判斷某個數x的第n位(如第3位)上是否為1,

    1)通過 x&00000100 的結果是否為0 來判斷。(不能根據是否等於1來判斷)

    2)通過(x>>3)&1 是否為0 來判斷

  2.通過number&bitMask的結果是否為0(不能用1判斷),bitMask=1不斷左移,可以將一個數的二進位制儲存到32位的陣列中。

	int number=100;
	int bitMask=1;
	for(int j=31;j>=0;j--) {
		int bit=number&bitMask;  //注意arr[i]&bitMask不一定等於1或者0,有可能等於00010000
		if(bit!=0)
			bitSum[j]+=1;
		bitMask=bitMask<<1;
	}

  3.通過以下程式碼實現二進位制轉化為數字(注意左移語句的位置):

	int result=0;
	for(int i=0;i<32;i++) {
		result=result<<1;
		result+=(bitSum[i]%3);
		//result=result<<1;  //不能放在後面,否則最前面一位就沒了
	}

  

更多:《劍指Offer》Java實現合集