題目:在乙個陣列 nums 中除乙個數字只出現一次之外,其他數字都出現了三次。請找出那個只出現一次的數字。
示例:
示例 1:
輸入:nums = [3,4,3,3]示例 2:輸出:4
輸入:nums = [9,1,7,9,7,9,7]這個題目和【力扣】136. 只出現一次的數字,面試題56 - i. 陣列中數字出現的次數是一類題目,基本解法有:雜湊表,排序,快慢指標,位運算。位運算是考察的重點,想要時間複雜度和空間複雜度達到最優,就需要進行位運算,那我們下面來看看這道題的三種解法,主要學習位運算的。輸出:1
雜湊表,就是[key,value],key儲存數字,value儲存出現次數,用hash.first可以訪問key,hash.second訪問second:
//1.雜湊表 o(n)s(n)
intsinglenumber1
(vector<
int>
& nums)
for(
auto i:hash)
return0;
}
這個思路也很簡單:
//2.排序
intsinglenumber2
(vector<
int>
& nums)
}return nums[i]
;//單個元素在結尾
}
有一說一,這個位運算真的很厲害,只要是**題沒有計算機底層原理表示不出來的。它的思路就是,有乙個數字出現了3次,那麼它的32位表示的二進位制之和,1的次數絕對也出現了3次。那麼根據這個原理,思路就出來了:
先加再移位
先移位再加
加 0:【0000,0000】;移位:【0000,0000】
移位:【0000,0000】;加0:【0000,0000】
加1:【0000,0001】;移位:【0000,0010】
移位:【0000,0000】;加1:【0000,0001】
加0:【0000,0010】;移位:【0000,0100】
移位:【0000,0010】;加0:【0000,0010】
加1:【0000,0101】;移位:【0000,1010】移位:【0000,0100】;加1:【0000,0101】
對比兩種辦法的結果,我們發現只有先移位,再加,才可以得到最後的結果,res才可以儲存b[i]中二進位制代表的數值。
那我們舉個例子,nums = [3,4,3,3] ,答案為4;深刻理解一下這兩步:給b[32]賦值;將b[32]%3後的值轉為整數。由於這個示例的最大值為4,所以我們只畫出b[32]的前8位即可。
那**如下:
int
singlenumber
(vector<
int>
& nums)
;//儲存所有數字每位2進製出現1的次數
//遍歷所有可能
for(
int i=
0;isize()
;i++
) flag<<=1;
//判斷下一位}}
//將b[32]中的二進位制,轉換為十進位制
int res=0;
//儲存最後的值
for(
int i=
31;i>=
0;i--
)//從高到低位如0134,從0開始,0101
return res;
}int
main()
加油哦!六一快樂呀,?。 面試題56 II 陣列中數字出現的次數 II
題目 解答 方法一 雜湊 class solution 雜湊表儲存數和其出現次數 std unordered mapunorderedmap for int num nums 遍歷雜湊表 for auto iter unorderedmap return0 方法二 異或 位運算 o n o 1 如果...
面試題56 陣列中數字出現的次數
題目一 乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。異或的基本性質 2個相同的數異或等於0,且異或操作 滿足結合律和交換律。首先 乙個整型陣列裡除了1個數字之外,其他的數字都出現了兩次。請寫程式找出這個只出現一次的數字。找出陣列中只出現一次的數 num...
面試題56 陣列中數字出現的次數
陣列中只出現一次的兩個數字。乙個整型陣列裡除兩個數字之外,其他數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度o n 空間複雜度o 1 例如,輸入陣列,因為只有4和6只出現了一次,其他數字出現了兩次,所以輸出4和6。先考慮這樣乙個問題,如果這個陣列中,只有乙個陣列出現1次,其餘數...