剣指offer-配列に一度しか現れない数字(python実装)


剣指offer-配列に一度しか現れない数字(python実装)
牛客網討論区の構想とプログラミングの実現を参考にするhttps://www.nowcoder.com/questionTerminal/e02fdb54d7524710a7d664d082bb7811
問題の説明
1つの整数配列には2つの数字を除いて偶数回の数字が現れた.プログラムを書いて、この2つの一度しか現れない数字を見つけてください.
実現構想.
Hash表の方法はみんな考えられますが、明らかに最善の方法ではありません.記述に他の数字が偶数回現れるという条件は用いられなかった.牛客網大神の書いた構想を参考にします:まず:位演算の中で異或の性質:2つの同じ数字の異或は0で、1つの数と0の異或はやはりそれ自身です.1つの数だけが1回現れると,配列中のすべての数を順番に異ならせたり演算したりして,最後に残ったのは落単の数であり,ペアで現れるものはすべて相殺されるからである.この考え方から,2つの数(ABと仮定する)が1回現れる配列を見た.私たちはまず先に異或で、残りの数字はA、B異或の結果に違いない.この結果のバイナリの中の1は、AとBの異なるビットを表現している.最初の1が存在するビット数をとり,3位であると仮定し,次に元の配列を2つのグループに分け,グループ化基準は3位が1であるか否かである.このように、同じ数は必ず1つのグループにあります.同じ数はすべてのビットが同じであるため、異なる数は、必ず1つのグループにありません.そしてこの2つのグループを最初の考え方に従って、順番に異なって、残りの2つの結果はこの2つの1回しか現れない数字です.
プログラミング実装
class Solution:
    def FindNumsAppearOnce(self, array):
        if not array:
            return []
        #  array          
        tmp = 0
        for i in array:
            tmp ^= i
        #   tmp    1   
        idx = 0
        while (tmp & 1) == 0:
            tmp >>= 1
            idx += 1
        a = b = 0
        for i in array:
            if self.isBit(i, idx):
                a ^= i
            else:
                b ^= i
        return [a, b]

    def isBit(self, num, idx):
        """
          num        idx    1
        :param num:   
        :param idx:          
        :return: num idx    1
        """
        num = num >> idx
        return num & 1