zoukankan      html  css  js  c++  java
  • LeetCode 137 只出现一次的数字 II

    LeetCode 137 只出现一次的数字 II

    虽然要求不开辟额外空间与O(n)的时间复杂度, 单由于数据比较水. 靠排序依然能过, 所以花了点时间想了想

    数字去重, 时间复杂度O(n)且不开辟额外空间, 那么就该从位运算入手了

    某个元素只出现一次, 其余每个元素出现3个, 则把每一个数字拆分为二进制, 经过拆分求和之后每一位上只有3x3x + 1, 经过%3后就完成了去重工作


    由此题意变成, 通过位运算设计加法器%3操作的数字电路

    由于最大数字为3, 至少需要2bit才能实现运算

    设运算数的低位为a, 高位为b, 输入为v

    每次计算结束时低位为an, 高位为bn

    位运算符号使用c语言版本

    至于具体设计, 就自由发挥了

    以下示意图均为随手瞎画, 没有遵循任何数字电路图规范_(:з」∠)_

    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;
    }
    
  • 相关阅读:
    HDU 5640 King's Cake
    HDU 5615 Jam's math problem
    HDU 5610 Baby Ming and Weight lifting
    WHU1604 Play Apple 简单博弈
    HDU 1551 Cable master 二分
    CodeForces659C Tanya and Toys map
    Codeforces 960E 树dp
    gym 101485E 二分匹配
    Codeforces 961E 树状数组,思维
    Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板
  • 原文地址:https://www.cnblogs.com/Simon-X/p/11415644.html
Copyright © 2011-2022 走看看