Single Number II

根据经验,要求O(n)复杂度的算法多要用到hashmap,所以naive的版本一代码如下,平均需要n/3的额外存储空间

class Solution {
public:
    int singleNumber(int A[], int n) {
        if(n==0)
        {
            return -1;
        }
        map<int,int> mmap;
        for(int i=0;i<n;++i)
        {
            if(mmap.count(A[i]))
            {
                mmap[A[i]]++;
            }
            else
            {
                mmap[A[i]]=1;
            }
        }
        for(map<int,int>::iterator itr=mmap.begin();itr!=mmap.end();++itr)
        {
            if(itr->second==1)
            {
                return itr->first;
            }
        }
        return -1;
    }
};

本题最优的解法是采用位操作,无奈对位操作还是不熟练,参看论坛大神代码如下:

https://oj.leetcode.com/discuss/6632/challenge-me-thx

public int singleNumber(int[] A) {
    int ones = 0, twos = 0;
    for(int i = 0; i < A.length; i++){
        ones = (ones ^ A[i]) & ~twos;
        twos = (twos ^ A[i]) & ~ones;
    }
    return ones;
}


另一个讲解更清楚的版本可以参看这里:

https://oj.leetcode.com/discuss/857/constant-space-solution

int singleNumber(int A[], int n) {
    int count[32] = {0};
    int result = 0;
    for (int i = 0; i < 32; i++) {
        for (int j = 0; j < n; j++) {
            if ((A[j] >> i) & 1) {
                count[i]++;
            }
        }
        result |= ((count[i] % 3) << i);
    }
    return result;
}


理解这个题以后,就可以推而广之,解决一系列类似这样的问题:“一组数中每个不同的数都出现a次,但有一个数不同,它出现b(b<a)次,求这个数”。

我们开一个数组 int k[ a],用k[i]来代表一个数,这个数中的每一位都出现过i次(即在n个数中,有一个数出现了i次,这样对这n个数做一个统计,就可以得到只有这个数满足每一位都出现过i次,k[i]就是这个数)

接下来就是遍历一遍原数组来填充和更新数组k中的值,每次从原数组拿到一个数,都要完整更新一次k数组,因为k数组记录的是不同出现次数的数,所以每次得到一个新的数都要完整更新k数组,有人会问那么如果有两个不同的数x,y,它们在原数组中都出现过c次,那么在k数组中k[ c ]代表的究竟是x还是y,答案是既不代表x,也不代表y。这也就是k数组只能复原出出现次数唯一的数。

int singleNumber(int A[],int n,int k, int l){
        int t;
        int* x = new int[k]();
        x[0] = ~0;
        for (int i = 0; i < n; i++) {
            t = x[k-1];
            for (int j = k-1; j > 0; j--) {
                x[j] = (x[j-1] & A[i]) | (x[j] & ~A[i]);
            }
            x[0] = (t & A[i]) | (x[0] & ~A[i]);
        }
<span style="white-space:pre">		</span>return x[l];
}
我理解的还是不太透彻,问题中的限制只能有一个“异类”,这个限制要如何突破暂不清楚,用上述代码做了测试,只能在满足只有一个“异类的情况下成功”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值