Операторы
a & b // AND
a | b // OR
a ^ b // XOR
a << k // shift
В Go ^x — битовое отрицание, а x ^ y — XOR.
XOR, маски и сдвиги компактно представляют множества и двоичные состояния.
Минимальный синтаксис, который понадобится в решении.
a & b // AND
a | b // OR
a ^ b // XOR
a << k // shift
В Go ^x — битовое отрицание, а x ^ y — XOR.
mask |= 1 << bit
has := mask&(1<<bit) != 0
mask &^= 1 << bit
&^ — AND NOT, удобен для очистки бита.
Три идиоматичных решения на Go с оценкой времени и памяти.
Пары взаимно уничтожаются через XOR.
O(n) time · O(1) spacefunc singleNumber(nums []int) int {
answer := 0
for _, n := range nums { answer ^= n }
return answer
}
n & (n−1) удаляет младшую единицу.
O(number of set bits) time · O(1) spacefunc hammingWeight(n uint32) int {
count := 0
for n != 0 {
n &= n - 1
count++
}
return count
}
У степени двойки установлен ровно один бит.
O(1) time · O(1) spacefunc isPowerOfTwo(n int) bool {
return n > 0 && n&(n-1) == 0
}