虽然要求不开辟额外空间与O(n)的时间复杂度, 单因为数据比较水. 靠排序依然能过, 因此花了点时间想了想设计
数字去重, 时间复杂度O(n)且不开辟额外空间, 那么就该从位运算入手了3d
某个元素只出现一次, 其他每一个元素出现3个, 则把每个数字拆分为二进制, 通过拆分求和以后每一位上只有3x
或3x + 1
, 通过%3
后就完成了去重工做code
由此题意变成, 经过位运算设计加法器
与%3
操做的数字电路blog
因为最大数字为3
, 至少须要2bit
才能实现运算排序
设运算数的低位为a
, 高位为b
, 输入为v
leetcode
每次计算结束时低位为an
, 高位为bn
it
位运算符号使用c语言版本二进制
至于具体设计, 就自由发挥了方法
如下示意图均为随手瞎画, 没有遵循任何数字电路图规范_(:з」∠)_im
因为an
的推导基本是同样的, 这里只列出an
部分的推导
将图转化为等式
c = a ^ v d = a & v e = b | d f = c ^ e
an = c & f bn = e & f
an = c & f = c & (c^e) = c & (~e) = c & (~(b|d)) = (a^v) & (~b) & (~d) = (a^v) & (~b) & (~(a&v)) = (a^v) & (~b) & (a|v) = (a^v) & (~b)
int singleNumber(int* nums, int numsSize){ int a = 0, b = 0; for (int i = 0; i < numsSize; ++i) { a = (a^nums[i]) & ~b; b = (~a & nums[i]) ^ b; } return a; }