↓快轉到主要內容
  1. LeetCode/

LeetCode 137: Single Number II

·1 分鐘· ·
LeetCode Medium Array Bit-Manipulation
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-11-10

  • 提交紀錄:Accepted(一次通過)

解題思路
#

XOR 只能抵消兩次。改成逐位元統計(Bit Manipulation):第 b 位上所有數的 1 加起來,出現三次的數貢獻 3 的倍數,所以 count % 3 就是答案在這一位的值。Python 的整數沒有固定位數,要用 32 位元處理:第 31 位是 1 時代表負數,減掉 2^32。

我的嘗試
#

一次 AC,當時是先排序,每三個一組檢查 nums[i] != nums[i + 2],第一個不完整的組就是答案;排序是 O(n log n),不符合線性時間的要求。

正確解法
#

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        res = 0
        for b in range(32):
            if sum((x >> b) & 1 for x in nums) % 3:
                res |= 1 << b
        return res - (1 << 32) if res >> 31 else res

複雜度
#

時間 O(32n),空間 O(1)。

要特別避免的錯誤
#

  • Python 對負數右移會補 1,(x >> b) & 1 在 b < 32 時剛好是補數表示的那一位。
  • 最後要把第 31 位是 1 的結果轉回負數。

面試口說整理
#

其他數都出現三次,所以我逐位元統計所有數這一位的 1 有幾個,取除以 3 的餘數就是答案這一位的值。Python 的整數沒有固定長度,最後第 31 位是 1 時要轉回負數。時間 O(32n)、空間 O(1)。

相關文章

LeetCode 287: Find the Duplicate Number
·1 分鐘
LeetCode Medium Array Two-Pointers Binary-Search Bit-Manipulation
LeetCode 287 解題筆記:把 i -> nums[i] 看成鏈結串列,重複的值就是環的入口,用 Floyd 判圈;O(1) 空間、不改陣列
LeetCode 78: Subsets
·1 分鐘
LeetCode Medium Array Backtracking Bit-Manipulation
LeetCode 78 解題筆記:每個元素選或不選;迭代寫法是每加入一個數,就把現有的每個子集合複製一份並加上它
LeetCode 90: Subsets II
·1 分鐘
LeetCode Medium Array Backtracking Bit-Manipulation
LeetCode 90 解題筆記:先排序;遇到跟前一個相同的數,只延伸上一步新產生的那些子集合
LeetCode 106: Construct Binary Tree from Inorder and Postorder Traversal
·1 分鐘
LeetCode Medium Array Hash-Table Divide-and-Conquer Tree
LeetCode 106 解題筆記:後序的最後一個是根;從後序尾巴往前取根時,要先建右子樹再建左子樹
LeetCode 48: Rotate Image
·1 分鐘
LeetCode Medium Array Math Matrix
LeetCode 48 解題筆記:順時針轉 90 度 = 先轉置再把每一列左右反轉,兩步都可以原地做
LeetCode 417: Pacific Atlantic Water Flow
·1 分鐘
LeetCode Medium Array Depth-First-Search Breadth-First-Search Matrix
LeetCode 417 解題筆記:反過來從海邊往內走,只能走到不比自己低的格子;兩個海都走得到的格子就是答案