137. 只出現一次的數字 II -詳解

題目描述

給定一個非空整數數組,除了某個元素只出現一次以外,其餘每個元素均出現了三次。找出那個只出現了一次的元素。

說明:

你的算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?

示例 1:

輸入: [2,2,3,2]
輸出: 3
示例 2:

輸入: [0,1,0,1,0,1,99]
輸出: 99

解法1

與Leetcode 136 不同的是,136是 2n+1, 可以直接異或,而這題是3n+1 .既然是3n+1 的思路,用 set 去重之後,*3 減去 不去重直接sum 就是重複之數的兩倍 ,對應解法一,O(n) ,但是set 用到了額外空間,所以這並不是 最符合題目要求 的解法。

 def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        r = (3* sum(set(nums)) - sum(nums)) // 2
        return r

解法2

如上所說,3n+12n+1 的區別在於 a ^ a 可以直接抵消,而 a ^ a ^a不能直接抵消,如果找到 3數抵消 的運算方式就可以解決問題。
在這裏插入圖片描述

  • 核心思路:可以看到 在 a,b = 0的基礎上,遍歷nums ,得到 i 。通過 a = (a^i) ; b= (b^i)的操作 可以將 i 賦值給 a,b,所以推出右邊的運算表達式,
    此時問題來了:當a =i時,b應該等於0 纔對啊,所以 b= (b^i) 需要作出調整, b= (b^i) = i ,而 i & ~i =0 ,此時 a=i,所以 i & ~a=0 ,所以 運算表達式變爲
   a =  (a ^ i)  & ~b
   b =  (b ^ i)  & ~a

拿測試用例:[2,2,3,2] 推演,過程如下,最終返回a值,即爲重複值。
時間複雜度爲O(n) 。

在這裏插入圖片描述

def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
		a, b = 0, 0
        for num in nums:
            a =  (a ^ num)  & ~b
            b =  (b ^ num)  & ~a
        return a
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章