題目連接:https://leetcode.com/problems/single-number-ii/description/html
題目大意:給出一串數,每一個數都出現三次,只有一個數只出現一次,把這個出現一次的數找出來。數組
法一:利用hashMap,空間換時間,可是好像也沒怎麼換到時間。代碼以下(耗時15ms):ide
1 public int singleNumber(int[] nums) { 2 Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 3 int ans = -1; 4 for(int i = 0; i < nums.length; i++) { 5 if(map.containsKey(nums[i])) { 6 map.put(nums[i], map.get(nums[i]) + 1); 7 } 8 else { 9 map.put(nums[i], 1); 10 } 11 } 12 for(int i = 0; i < nums.length; i++) { 13 if(map.get(nums[i]) == 1) { 14 ans = nums[i]; 15 break; 16 } 17 } 18 return ans; 19 }
法二:先排序,再一一計算。代碼以下(耗時5ms):spa
1 public int singleNumber(int[] nums) { 2 Arrays.sort(nums); 3 int ans = nums[0]; 4 int cnt = 1; 5 int length = nums.length; 6 for(int i = 1; i < length; i++) { 7 if(nums[i] != nums[i - 1]) { 8 if(cnt == 1) { 9 break; 10 } 11 ans = nums[i]; 12 cnt = 1; 13 } 14 else { 15 cnt++; 16 } 17 } 18 return ans; 19 }
法三(借鑑):利用位運算,這個方法是廣泛方法,136題也能夠用這個方法作,可是時間複雜度實際上是o(n^2),因此也不是最優的,只是用到了位運算。借鑑自:http://blog.csdn.net/feliciafay/article/details/19004479。代碼以下(耗時7ms):.net
1 public int singleNumber(int[] nums) { 2 int ans = 0; 3 int length = nums.length; 4 //將每個數取二進制位按位相加,若是都是重複的則當前位的相加和必定是3的倍數,不然當前位必定存在於要找的那個數中 5 //好比1,1,1,2,2,2,3這六個數將其轉爲二進制數按位相加,而後每一位都對3取模,最後必定能夠獲得3 6 for(int i = 0; i < 32; i++) {//計算每一位 7 int sum = 0;//統計每一位的和 8 for(int j = 0; j < length; j++) {//對每一個數取第i位的數值 9 if(((nums[j] >> i) & 1) == 1) {//取第i位的數值 10 sum++;//將每一個數第i位的值相加求和 11 sum %= 3; 12 } 13 } 14 if(sum != 0) {//若是對3取模後非0,則說明當前位必定是要找的數的某一位 15 ans |= sum << i;//將其轉爲十進制加入結果當中 16 } 17 } 18 return ans; 19 }
法四(借鑑):這個位運算還沒看懂。https://www.cnblogs.com/yangrouchuan/p/5323327.htmlcode
1 連接:https://www.nowcoder.com/questionTerminal/e02fdb54d7524710a7d664d082bb7811 2 來源:牛客網 3 4 /** 5 * 數組中有兩個出現一次的數字,其餘數字都出現兩次,找出這兩個數字 6 * @param array 7 * @param num1 8 * @param num2 9 */ 10 public static void findNumsAppearOnce(int [] array,int num1[] , int num2[]) { 11 if(array == null || array.length <= 1){ 12 num1[0] = num2[0] = 0; 13 return; 14 } 15 int len = array.length, index = 0, sum = 0; 16 for(int i = 0; i < len; i++){ 17 sum ^= array[i]; 18 } 19 for(index = 0; index < 32; index++){ 20 if((sum & (1 << index)) != 0) break; 21 } 22 for(int i = 0; i < len; i++){ 23 if((array[i] & (1 << index))!=0){ 24 num2[0] ^= array[i]; 25 }else{ 26 num1[0] ^= array[i]; 27 } 28 } 29 } 30 /** 31 * 數組a中只有一個數出現一次,其餘數都出現了2次,找出這個數字 32 * @param a 33 * @return 34 */ 35 public static int find1From2(int[] a){ 36 int len = a.length, res = 0; 37 for(int i = 0; i < len; i++){ 38 res = res ^ a[i]; 39 } 40 return res; 41 }