第2章 面試需要的基礎知識
第3章 高質量的代碼
第4章 解決面試題的思路
第5章 優化時間和空間效率
面試題39 : 數組中出現次數超過一半的數字
面試題40 : 最小的k個數
面試題42 : 連續子數組的最大和
面試題43 : 從1到n整數中1出現的次數
面試題45 : 把數組排成最小的數
面試題49 : 醜數
面試題50 : 第一個只出現一次的字符
面試題51 : 數組中的逆序對
面試題52 : 兩個鏈表的第一個公共結點
面試題53 : 在排序數組中查找數字
面試題55 : 二叉樹的深度、平衡二叉樹
面試題56 :數組中數字出現的次數
第6章 面試中的各項能力
第7章 兩個面試案例
題目描述
牛客網
一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。要求時間複雜度O(n),空間複雜度O(1)。
解題分析
首先想到的是一道相似題型:一個整型數組裏除了一個數字之外,其他的數字都出現了兩次。這道題使用異或運算遍歷一遍數組即可,但是本題有兩個不同數,簡單遍歷一遍做異或運算顯然不行。
假如我們能把這兩個不同的數分開到兩個數組中,也就是把原數組分成兩個數組,每個數組包含一個只出現一次的數,那麼就可以用異或運算求解了。
難點在於如何把這兩個數分開放入到不同數組中。
我們還是從頭到尾依次異或數組中每個數,得到的異或結果就是那兩個次數爲1的異或結果,那麼異或結果的二進制表示中至少有一位爲1。找到這個異或結果中從右起第一位爲1的位置,假設位置爲index,然後對數組中所有數判斷他們二進制形式下index位上是否爲1,爲1的分爲一組,不爲1的分爲一組,這樣數組就分爲兩組,並且那兩個次數爲1的數被分到不同組中了。然後分別對兩組數組異或,返回結果即可。
舉例:[2, 4, 3, 6, 3, 2, 5, 5]
- 對數組每個數異或結果爲得到0010;
- 根據數字的右起第二位是否爲1,將數組分爲[2, 3, 6, 3, 2],[4, 5, 5];
- 分別對上述兩個數組異或,得到6和4。
實戰
class Solution:
# 返回[a,b] 其中ab是出現一次的兩個數字
def FindNumsAppearOnce(self, array):
# write code here
if not array or len(array) % 2:
return None
# 找到兩個不同數異或結果中最右邊的1
number = 0
digit = 1
for num in array:
number ^= num
while number:
if not number % 2:
number = number >> 1
digit = digit << 1
else:
break
# 劃分數組,同時計算異或
a, b = 0, 0
for num in array:
if num & digit:
a ^= num
else:
b ^= num
return [a, b]