【leetcode系列】【面試題】【中等】數組中數字出現的次數(位運算、二分)

題目:

題目鏈接: https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/

 

解題思路:

方法一:異或,時間O(N),空間O(1)

如果只有一個數字不重複,那隻要從第一個數字異或到最後一個數字的結果,就是不重複的數字

但是如果有兩個數字不重複,那異或的結果,就是兩個不重複數字的異或結果

如果能夠把兩個數字分到兩組,其他數字保證相同的數字分到一組,那對兩組數字分別進行異或操作,最後就可以得到這兩個不同的數字了

所以在對所有數字異或操作,獲得一個新的數字之後,從新的數字中,選取一個二進制表示中是1的位,說明這一位在兩個要找的數字中一個爲0,一個未1

根據這一位進行分組,可以保證將兩個要找的數字分到兩個組裏,並且其餘相同的數字在同一組

 

方法二:二分,時間O(NlogN),空間O(N)

這種方法效率比第一種低,但是覺得思路挺好的,也記錄下來

原題解鏈接: 什麼?這題還可以用二分查找?🤷‍♀️必須秒懂!

大致思路爲:

  1. 先遍歷數組,尋找最大的數字right和最小的數字left
  2. 然後根據中間數組mid = (left + right) / 2進行分組,也是分別進行異或操作
  3. 如果兩組數組中,有一個數字爲0,說明兩個要尋找的不重複數字在同一組,更新left或者right,再次進行分組異或,直到兩組數字的最終異或結果都不爲0
  4. 需要額外處理的情況,是可能兩個不重複數字中,有一個爲0,需要在第一次遍歷確定left和right的時候進行記錄數字0的個數

 

 

 

代碼實現:

方法一:

class Solution:
    def singleNumbers(self, nums: List[int]) -> List[int]:
        res_num = 0
        for a in nums:
            res_num ^= a

        bit_pos = 1
        while bit_pos < res_num:
            if (res_num & bit_pos) == bit_pos:
                break

            bit_pos <<= 1

        res = [0, 0]
        for a in nums:
            idx = 0 if (a & bit_pos) == 0 else 1
            res[idx] ^= a

        return res

 

方法二:

class Solution:
    def singleNumbers(self, nums: List[int]) -> List[int]:
        left = float('inf')
        right = float('-inf')
        res = 0
        zero_num = 0
        for a in nums:
            left = min(left, a)
            right = max(right, a)
            if a == 0:
                zero_num += 1

            res ^= a

        if zero_num == 1:
            return [0, res]

        while left <= right:
            res = [0, 0]
            mid = (left + right) // 2
            for a in nums:
                if a < mid:
                    res[0] ^= a
                else:
                    res[1] ^= a

            if res[0] != 0 and res[1] != 0:
                return res
            elif res[0] == 0:
                left = mid
            else:
                right = mid

        return res

 

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