LeetCode 137 只出現一次的數字 II

LeetCode 137 只出現一次的數字 II

雖然要求不開闢額外空間與O(n)的時間複雜度, 單因爲數據比較水. 靠排序依然能過, 因此花了點時間想了想設計

數字去重, 時間複雜度O(n)且不開闢額外空間, 那麼就該從位運算入手了3d

某個元素只出現一次, 其他每一個元素出現3個, 則把每個數字拆分爲二進制, 通過拆分求和以後每一位上只有3x3x + 1, 通過%3後就完成了去重工做code


由此題意變成, 經過位運算設計加法器%3操做的數字電路blog

因爲最大數字爲3, 至少須要2bit才能實現運算排序

設運算數的低位爲a, 高位爲b, 輸入爲vleetcode

每次計算結束時低位爲an, 高位爲bnit

位運算符號使用c語言版本二進制

至於具體設計, 就自由發揮了方法

如下示意圖均爲隨手瞎畫, 沒有遵循任何數字電路圖規範_(:з」∠)_im

0

方法一

1

方法二

2

方法三

因爲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)

C

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;
}
相關文章
相關標籤/搜索