题目
输入一个整数数组,数组中只有一个数字出现了一次,而其他数字都出现了3次。请找出那个只出现一次的数字。例如,如果输入的数组为[0,1,0,1,0,1,100],则只出现一次的数字是100。
解题思路
-
异常情况:数组为空,直接返回。
-
如果一个数字出现三次,这三个数的二进制形式的同一位数相加的结果,除 3 的余数肯定为 0。因为同一位相加的结果不是 0 就是 3。
-
那当前位数除 3 的余数结果就是只出现一次的数字的当前位数值。
-
初始化一个32位的数组来存放每一位的累加和。
-
累加循环条件:1层循环遍历每个数字,2层循环遍历每个数字的32位(0-31)。获取 num 的第 i 位的二进制数值公式: num >> (31 - i) & 1。
-
该公式也可以替换为 num >> (32 - i) & 1,然后内层循环要变成 1 - 32,内部的赋值要变为 binaryNums[i - 1] += num >> (32 - i) & 1。
-
生成最后的结果:遍历累加和的数组,左移一位然后加上获得当前位除 3 的余数(即只出现一次的数字的二进制形式当前位数值)。
代码实现
class OnlyOneTime {
static func onlyOneTime(_ nums: [Int]) -> Int {
if nums.isEmpty { return 0 }
var binaryNums: [Int] = Array(repeating: 0, count: 32)
for num in nums {
for i in 0...31 {
binaryNums[i] += (num >> (31 - i)) & 1
}
}
// 此处需用 32 位,如果用 Int 的话,数组中有负数则会将其解释为无符号整数,比如 -4 会被解释为 4294967292
var result: Int32 = 0
for binaryNum in binaryNums {
result = Int32(result << 1) + Int32(binaryNum % 3)
}
return Int(result)
}
}