1. 程式人生 > >位運算-出現k次與出現一次

位運算-出現k次與出現一次

題目:陣列中arr只有一個數出現了1次,其他的數都出現了k次,請輸出這個只出現了一次的數。

思路:這道題目要求使用位運算實現,如果採用資料結構Map就會簡單很多。解此題前先了解不進位加法的思想,比如兩個二進位制數10+10 進行不進位加法得到的結果是00(二進位制),再比如10個51進行不進位加法結果也為00(十進位制),這裡就可以得出結論,如果K個相同的K進位制數進行無進位加法,相加的結果一定是每一位上都為0的K進位制數。那麼這道題的思路就是,構造一個二位陣列kRadix,其中一維索引是陣列arr的長度,二位索引存的就是每個數字的三進位制字串再反轉過後的字元陣列,這裡要反轉的目的是因為陣列arr轉化成三進位制陣列時的長度不一樣,反轉過後的字串高位補0,這樣高低位就對齊了,這樣才能進行不進位加法。然後對每一列採用不進位加法,將結果存進一個一維陣列resArr,再然後遍歷這個陣列分別對K求餘累加算出十進位制,得出的資料就是唯一的那個數。

程式碼:

public class 出現K次 {

	public static void main(String[] args) {
		int []arr = {2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
		int len = arr.length;
		char [][] kRadix = new char[len][];
		int k = 3;
		// 轉成k進位制字元陣列
		int maxLen = 0;
		// 對於每個數字
		for (int i = 0; i < len; i++) {
			// 求每個數字的三進位制字串並反轉,然後轉為字元陣列
			kRadix[i] = new StringBuilder(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
			if (kRadix[i].length>maxLen) {
				maxLen = kRadix[i].length;
			}
		}
		int [] resArr = new int[maxLen];
		// 不進位加法
		for (int i = 0; i < len; i++) {
			// 不進位加法
			for (int j = 0; j < maxLen; j++) {
				if (j>=kRadix[i].length) {
					resArr[j] += 0;
				}else {
					resArr[j] += (kRadix[i][j]-'0'); // kRadix[i][j]-'0' 字元-'0'  從字元轉換成了數字
				}
			}
		}
		int res = 0;
		for (int i = 0; i < maxLen; i++) {
			res += (resArr[i] % k ) * (int)(Math.pow(k, i));  // 累加求出十進位制
		}
		System.out.println("陣列中唯一出現的數字是:"+res);

	}

}

結果: