这是一个LeetCode问题。我在该问题的不同版本中写了4个答案。当我尝试使用"位操作"时,我收到了错误。由于LeetCode中没有人可以回答我的问题,而且我无法找到任何有关此问题的Swift文档。我以为我会试着在这里问。
问题是在给定数组中获得多数元素(> n / 2)。以下代码适用于其他语言,如 Java ,因此我认为它可能是Swift中的一般问题。
func majorityElement(nums: [Int]) -> Int {
var bit = Array(count: 32, repeatedValue: 0)
for num in nums {
for i in 0..<32 {
if (num>>(31-i) & 1) == 1 {
bit[i] += 1
}
}
}
var ret = 0
for i in 0..<32 {
bit[i] = bit[i]>nums.count/2 ? 1 : 0
ret += bit[i] * (1<<(31-i))
}
return ret
}
当输入为 [ - 2147483648] 时,输出为2147483648.但在Java中,它可以成功输出正负数。
Swift doc说:
即使在32位平台上,Int也可以存储-2,147,483,648和2,147,483,647之间的任何值,并且对于许多整数范围来说足够大。
嗯, 2,147,483,647 ,输入比该数字大1。当我在游乐场中运行pow(2.0, 31.0)
时,会显示 2147483648 。我很困惑。我的代码有什么问题,或者我错过了什么 Swift Int ?
答案 0 :(得分:2)
Java int
是32位整数。 Swift Int
是32位或64位
取决于平台。特别是,它在所有OS X上都是64位
可以使用Swift的平台。
您的代码只处理给定整数的低32位,因此
-2147483648 = 0xffffffff80000000
变为
2147483648 = 0x0000000080000000
因此解决问题,您可以更改函数以将32位整数作为参数:
func majorityElement(nums: [Int32]) -> Int32 { ... }
或通过计算使其适用于任意大小的整数
实际大小和使用而不是常量32
:
func majorityElement(nums: [Int]) -> Int {
let numBits = sizeof(Int) * 8
var bit = Array(count: numBits, repeatedValue: 0)
for num in nums {
for i in 0..<numBits {
if (num>>(numBits-1-i) & 1) == 1 {
bit[i] += 1
}
}
}
var ret = 0
for i in 0..<numBits {
bit[i] = bit[i]>nums.count/2 ? 1 : 0
ret += bit[i] * (1<<(numBits-1-i))
}
return ret
}
更灵活的方式是使用map()
和reduce()
func majorityElement(nums: [Int]) -> Int {
let numBits = sizeof(Int) * 8
let bitCounts = (0 ..< numBits).map { i in
nums.reduce(0) { $0 + ($1 >> i) & 1 }
}
let major = (0 ..< numBits).reduce(0) {
$0 | (bitCounts[$1] > nums.count/2 ? 1 << $1 : 0)
}
return major
}