136.Single Number---異或、位運算

題目連接數組

題目大意:給出一串數組,裏面的數都是兩個,只有一個數是一個,把這個只有一個的數找出來。時間複雜度最好是線性的,空間複雜度最好爲O(1).ide

法一:利用map,空間換時間,代碼以下(耗時26ms):spa

 1     public int singleNumber(int[] nums) {
 2         Map<Integer, Integer> map = new HashMap<Integer, Integer>();
 3         int res = -1;
 4         for(int i = 0; i < nums.length; i++) {
 5             if(map.get(nums[i]) != null && map.get(nums[i]) == 1) {
 6                 map.put(nums[i], 2);
 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                 res = nums[i];
15                 break;
16             }
17         }
18         return res;
19     }
View Code

法二:先排序,再一個for循環,依次比較,代碼以下(耗時8ms):code

 1     public int singleNumber(int[] nums) {
 2         Arrays.sort(nums);
 3         int res = nums[0];
 4         int cnt = 1;
 5         boolean flag = false;
 6         for(int i = 1; i < nums.length; i++) {
 7             if(nums[i] != nums[i - 1]) {
 8                 if(cnt == 1) {
 9                     res = nums[i - 1];
10                     flag = true;
11                     break;
12                 }
13                 cnt = 1;
14             }
15             else {
16                 cnt++;
17             }
18         }
19         if(flag == false) {
20             res = nums[nums.length - 1];
21         }
22         return res;
23     }
View Code

法三(借鑑):利用異或,由3^3=0知道,相同的兩個數異或爲0,不一樣的兩個數異或爲1。代碼以下(耗時1ms):blog

1     public int singleNumber(int[] nums) {
2         int res = nums[0];
3         for(int i = 1; i < nums.length; i++) {
4             res = res ^ nums[i];
5         }
6         return res;
7     }
View Code

 法四(借鑑):利用137題的法三,位運算,只是把對3取模改爲對2取模便可。(num>>i)&1取num的第i位二進制數。ans |= sum <<i將二進制相加轉爲十進制。代碼以下(耗時12ms):排序

 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 %= 2;
12                 }
13             }
14             if(sum != 0) {//若是對3取模後非0,則說明當前位必定是要找的數的某一位
15                 ans |= sum << i;//將其轉爲十進制加入結果當中
16             }
17         }
18         return ans;
19     }
View Code
相關文章
相關標籤/搜索