劍指Offer_#56-II_ 陣列中數字出現的次數II
阿新 • • 發佈:2020-07-23
劍指Offer_#56-II_ 陣列中數字出現的次數II
劍指offerContents
題目
在一個數組 nums 中除一個數字只出現一次之外,其他數字都出現了三次。請找出那個只出現一次的數字。
示例 1:
輸入:nums = [3,4,3,3]
輸出:4
示例 2:
輸入:nums = [9,1,7,9,7,9,7]
輸出:1
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
思路分析
思路是統計數字的二進位制表示中每一位出現的次數。
- 對於出現3次的數字,每個二進位制位也出現3次;多組出現3次的數字疊加,每個二進位制位出現次數是3的倍數。
- 再考慮只出現一次的數字,即我們的目標數字。目標數字中,出現1的二進位制位會增加到之前的統計次數中,使得這個位置出現1的總次數不再是3的倍數。
演算法流程
- 遍歷陣列,對於每個元素,迴圈右移位,通過掩碼1獲取到二進位制表示中每一位1出現的次數,儲存到一個輔助陣列中,索引表示第幾位,元素表示出現的次數。
- 遍歷剛才的輔助陣列,看每個元素對3取餘的結果
- 若為0說明這一位出現了3的整數倍次,必然沒有在目標數字中出現過,所以不計算
- 若不為0,說明這位數字出現在目標數中,res加上digit,也就是當前二進位制位的數量級(2n)
解答
class Solution {
public int singleNumber(int[] nums) {
int res = 0;
//二進位制中每一位數字的數量級
int digit = 1;
//統計二進位制表示中每一位出現的總個數
int[] numTimes = new int[32];
for(int num:nums){
for(int i = 0; i <= 31;i++){
//如果第i位是1,那麼help[i]增加1
numTimes[i] += (num & 1 );
//繼續統計下一位
num >>= 1;
}
}
//遍歷help[]陣列
for(int times:numTimes){
res += digit * (times % 3);
digit <<= 1;
}
return res;
}
}
複雜度分析
時間複雜度:O(n),兩層迴圈中,第二層迴圈次數是常數,所以還是O(n)。
空間複雜度:O(1),藉助一個輔助陣列,其長度是常數。