[經典算法][Python][異或運算]缺失整數

題目1

一個無序的數組裏面有若干個正整數,範圍是1-100,其中的99個整數都出現了偶數次,只有1個整數出現了奇數次,如何找到這個出現奇數次的整數?

思路

遍歷整個數組,依次做異或運算。由於異或運算在進行運算時,相同爲0,不同爲1,因此所有出現偶次的整數都會相互抵消成爲0,只有唯一出現奇數的整數會被留下。
如:

無序數組 3 1 3 2 4 1 4
異或運算 3 xor 1 xor 3 xor 2 xor 4xor 1 xor 4 xor =2

假設數組長度爲n,那麼該解法的時間複雜度是O(n),空間複雜度爲O(1)。

題目2

假設一個無序數組裏有若干個正整數,範圍是1-100,其中有98個整數出現了奇數次,其他的整數出現偶數次。如何找出這個2個出現奇次整數?

思路

把2個出現奇數次的整數命名爲A和B,遍歷整個數組,然後依次做異或運算,進行異或運算的最終結果,等於A和B進行異或運算的結果。在這個結果中,至少有一個二進制單位是1(如果是0,說明A和B相等。和題目不符)
如:無序數組{4,1,2,2,5,1,4,3},所有元素進行異或運算的結果是00000110B

無序數組 4 1 2 2 5 1 4 3
異或運算 1 xor 1 xor 2 xor 2 xor 5xor 1 xor 4 xor 3 xor 00000110B

選定該結果中的值爲1的某一位數字,如00000110B的倒數第2位是1,這說明對應的A和B的二進制的倒數第2位是不同的。其中必定有一個是0,有一個是1
根據這個結論可以把原來的數字按照二進制的倒數第2位的不同,分爲兩個部分,一部分的倒數第2位是0,另外一部分的倒數第2位是1。如:
5—>>二進制—>>101
3—>>二進制—>>011
倒數第2位,一個是0,一個是1
所以按照以上方法可將數組分爲:
4,1,5,1,4和2,2,3兩個部分。
接下來按照原來的異或運算,從每一部分找出唯一的奇數次即可。
假設數組長度爲n,那麼該解法的時間複雜度是O(n)。把數組分成兩個部分,並不需要額外的存儲空間,完全可以按照二進制位分組的同時來做異或運算,所以空間複雜度仍然是O(1)。

代碼

def findLostNumber(array):
   # 用於存儲出現奇次的整數
   resultList = [0 for i in range(2)]
   # 第一次做整體異或運算
   xorResult = 0;
   for i in array:
       xorResult^=i
   if xorResult==0:
       return None
   # 確定2個整數的不同位,以此來做分組
   separator = 1
   while 0==(xorResult&separator):
       separator<<=1;

   # 第二次分組進行異或運算
   for j in array:
       if 0==(separator&j):
           resultList[0]^=j
       else:
           resultList[1]^=j
   return resultList

if __name__ == '__main__':
   array = [4,1,2,2,5,1,4,3]
   res = findLostNumber(array)
   print(res)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章