劍指offer第二版(Python3)--面試題56 :數組中數字出現的次數

第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]

  1. 對數組每個數異或結果爲得到0010;
  2. 根據數字的右起第二位是否爲1,將數組分爲[2, 3, 6, 3, 2],[4, 5, 5];
  3. 分別對上述兩個數組異或,得到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]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章