Leetcode算法学习日志-137 Single Number II

Leetcode 137 Single Number II

题目原文

Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

题意分析

给定一个数组,数组中有一个元素只出现一次,其余元素出现3次,找出出现一次的那个元素。需要在O(n)时间完成,且不需要额外存储。

解法分析

本题不能有额外存储,也就不能采用散列表来记录,但可以定义一些int变量。这种题型都是采用bit manipulation。从32个比特来看,我们需要对每一个比特构造一个计数器,需要一个32长度的数组来存储,如果某一比特为1的个数为6,表示只出现一次的那个元素在该比特为0,该数组可以表示如下:

1 3 6 11 9 .............................

因为我们只关心模3取余的结果,所以上述计数器又可以表示如下:

1 0 0 2 0................................

可以看到上述计数器只有三个状态,0,1,2,分别表示该比特为1的数字出现次数为3n,3n+1,3n+2,因此上述三种状态可以用两比特来表示,a和b,对于每一比特的三种状态的表示如下:

a b

0 0 3n

01 3n+1

10 3n+2

因此,对于每次加入的数c,可以得到ab的状态转移表:


由此可以写出a和b的表达式,a=a&(~b)&(~c)^(~a)&b&c,b=(~a)&b&(~c)^(~a)&(~b)&c。这是每一比特的状态转移,a和b是32bit数,对于他们的每一位都进行同样的状态转移操作,得到的b就是那个只出现一次的数(b的某一位为1正好表征计数器为3n+1的状态,说明只出现一次的数在该位是1)。C++代码如下:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int a=0,b=0;
        int temp;
       // int c;
        for(int c:nums){//c should be redefined int every iteration
            temp=(a&(~b)&(~c))^((~a)&b&c);
            b=((~a)&(b)&(~c))^((~a)&(~b)&c);
            a=temp;
        }
        return b;
        
        
    }
};






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值