您的位置:首页 > 其它

[ LeetCode ] Single Number II [4]

2014-06-04 10:31 141 查看

题目

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

Note:

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

原题地址

解题思路

数组中含有n个数,其中一个数只出现1次,其余个数均出现3次,就只出现1次的数。

首先应该想到的就是计数法,先对数组排序,然后统计每个数出现的次数,找出出现次数为1个数;

更高级一点的方法还是用位运算,充分发掘数字二进制中的0和1出现的规律。一个数字是由0和1组成的,如果这个数字出现3次,那么这个数字中各个位上0和1出现的次数也应该是3次。按照这样统计数组中所有数的各个位1的个数,如果个数是1个倍数,这所求数字该位不为1。

举例如下:

数组: 1, 3, 1, 5, 1, 6, 5, 6, 6, 5

对应的二进制位 001, 011, 001, 101, 001, 110, 101, 110, 110, 101

从右往左看:

第1位 1 的个数为 7,则所求结果数字中的第1位也应该为1;

第2位 1 的个数为 4,则所求结果数字中的第2位也应该为1;

第3位 1 的个数为 6,则所求结果数字中的第3位为0。

根据上面的分析所得结果为 011,即为3。

代码实现

代码一:排序计数
class Solution {
public:
    int singleNumber(int A[], int n) {
        if(A==NULL || n<=0) return 0;
        sort(A, A+n);
        int count = 1;
        int ret = A[0];
        for(int i=1; i<n; ++i){
            if(A[i] == A[i-1])
                ++count;
            else{
                if(count == 1){
                    break;
                }
                else if(count ==  3){
                    count = 1;
                }
            }
            ret = A[i];
        }
        return ret;
    }
};

代码二:位运算
class Solution {
public:
    int singleNumber(int A[], int n) {
        if(A==NULL || n<=0) return 0;
        int count = 0;
        int ret = 0;
        for(int i=0; i<32; ++i){
            count = 0; 
            int d = 1<<i;
            for(int j=0; j<n; ++j){
                if( A[j] & d )
                    ++count;
            }
            if(count % 3 != 0)
                ret = ret | d;
        }
        return ret;
    }
};


如果你觉得本篇对你有收获,请帮顶。

另外,我开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
你可以搜索公众号:swalge 或者扫描下方二维码关注我



(转载文章请注明出处: http://blog.csdn.net/swagle/article/details/28394529 )
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: