1. 题目

137. 只出现一次的数字 II
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

示例 1
输入:nums = [2,2,3,2]
输出:3

示例 2
输入:nums = [0,1,0,1,0,1,99]
输出:99

提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1

2. 题解

2.1 解法1 (数学法)

from typing import List

# 数学法
# 假设 nums = [a, a, a, b, b, b, c]
# 结果为 3 * (a + b + c) - (a + a +a + b + b +b + c) = 2c
class Solution:
def singleNumber(self, nums: List[int]) -> int:
return (3 * (sum(set(nums))) - sum(nums)) // 2


if __name__ == "__main__":
s = Solution()
a = s.singleNumber([2,2,1])
print(a)

2.2 解法2 (复杂)

class Solution:
def singleNumber(self, nums: List[int]) -> int:
counts = [0] * 32
for n in nums:
for j in range(32):
counts[j] += n & 1
n >>= 1 # 进行右移
res, m = 0, 3 # m表示 3的次数
# 对每一位上的1个数取余
for i in range(32):
res <<= 1
res |= counts[31 - i] % m

return res if counts[31] % m == 0 else ~(res ^ 0xffffffff)

2.3 解法3 (位方法)

from typing import List


class Solution:
def singleNumber(self, nums: List[int]) -> int:
one, two = 0, 0
for n in nums:
one ^= n
two |= (one & n)
three = (one & two)

# 如果相应的位出现3次,则将改为重置位0
two &= ~three
one &= ~three
return one


if __name__ == "__main__":
s = Solution()
a = s.singleNumber([2,2,1])
print(a)