劍指 Offer 56 - II. 陣列中數字出現的次數 II(map、位運算)2
阿新 • • 發佈:2021-01-17
技術標籤:LeetCode
在一個數組 nums 中除一個數字只出現一次之外,其他數字都出現了三次。請找出那個只出現一次的數字。
示例 1:
輸入:nums = [3,4,3,3]
輸出:4
示例 2:
輸入:nums = [9,1,7,9,7,9,7]
輸出:1
解法一:雜湊map
class Solution { // 使用 HashMap 記錄各個數字出現的次數 public int singleNumber(int[] nums) { Map<Integer, Integer> map = new HashMap(); for(int i = nums.length - 1; i >= 0; --i){ int key = nums[i]; if(!map.containsKey(key)){ // 如果之前沒有遇到這一數字,則放入 map 中 map.put(key, 1); }else{ // 如果之前遇到過這一數字,則出現次數加 1 map.put(key, map.get(key) + 1); } } for(Map.Entry<Integer, Integer> entry: map.entrySet()){ if(entry.getValue() == 1){ return entry.getKey(); } } return -1; } }
解法二:位運算
public class Solution { public int singleNumber(int[] nums) {//本演算法同樣適用於陣列nums中存在負數的情況 if(nums.length==0) return -1;//輸入陣列長度不符合要求,返回-1; int[] bitSum = new int[32];//java int型別有32位,其中首位為符號位 int res=0; for(int num:nums){ int bitMask=1;//需要在這裡初始化,不能和res一起初始化 for(int i=31;i>=0;i--){//bitSum[0]為符號位 //這裡同樣可以通過num的無符號右移>>>來實現,否則帶符號右移(>>)左側會補符號位,對於負數會出錯。 //但是不推薦這樣做,最好不要修改原陣列nums的資料 if((num&bitMask)!=0) bitSum[i]++;//這裡判斷條件也可以寫為(num&bitMask)==bitMask,而不是==1 bitMask=bitMask<<1;//左移沒有無符號、帶符號的區別,都是在右側補0 } } for(int i=0;i<32;i++){//這種做法使得本演算法同樣適用於負數的情況 res=res<<1; res+=bitSum[i]%3;//這兩步順序不能變,否則最後一步會多左移一次 } return res; } }