位運算-出現k次與出現一次
阿新 • • 發佈:2019-01-10
題目:陣列中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); } }
結果: