Single Number通用解法

题目:
给定一个整数数组,每个元素出现3次除了一个元素,找到唯一的那个元素。
注意:
算法必须是线性时间复杂度。你能不使用额外的内存实现它吗?

思路:
single numer本质就是用一个数记录每个bit出现的次数,当数的某一位出现了指定次数就归0(本题是3次)。
假设当出现2次就归0时,很容易想到可以使用异或的方法。
然而,当出现2次以上时,我们就需要增加记录的数,因为一个数每个bit,只有0,1两种可能,只能记录两种。
此处我们就需要使用两个数分别secondbit,firstbit来进行记录,可以表示4种可能,本题只需要3种00,01,10。

然后,使用卡诺图来得到secondbit,firstbit的表达式,分别简化secondbit,firstbit为符号f,s则有:

f卡诺图:

sf\A[i] 0 1
00 0 1
01 1 0
10 0 0

因此有: f = (~s&~f&A[i])|(~s&f&~A[i])

s卡诺图:

sf\A[i] 0 1
00 0 0
01 0 1
10 1 0

因此有: s = (~s&f&A[i])|(s&~f&~A[i])

此外当except one 可能出现1次,也可能出现2次。最后的 s f 可能为 00,01,10 结果就是 a|b,有1出现则此位置为1否则为0

    int singleNumber(int A[], int n) {
        int firstbit = 0,secondbit = 0;
        int one = 0;
        for(int i = 0;i < n; i++){
            one = firstbit;
            firstbit = (~secondbit&~firstbit&A[i])|(~secondbit&firstbit&~A[i]);
            secondbit = (~secondbit&one&A[i])|(secondbit&~one&~A[i]);
        }
        return firstbit|secondbit;
    }

用卡诺图化简函数基本步骤:
1. 填入真值表
2. 尽可能画大圈(包含2^n个真值)
3. 把所有真值为1的包括

参考:
SingleNumer问题牛客网讨论
处理SingleNumer的通用方式
卡诺图

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hujinglovekmg/article/details/78645560
个人分类: c++算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭