56-02 数组中唯一只出现一次的数字

题目

在一个数组中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

LeetCode

C++ 题解

如果题目中的“三次”换成“两次”,这道题目将非常简单,因此两个相同的数字异或,每一位都会变成0,其实亦或也可以看成两个数字的每一个二进制位对应进行加法后对2取模后的结果。按照这种思路,对于出现三次的数字,改成对3取模即可。
举个例子说明下(10,4,5,5,4,4,5)

相关数字对应二进制表示:10 = 1010 4 = 0100 5 = 0101
1)申请一个长度为32(因为int占32bit)的int型数组bitsum,用于记录整型数字每一位出现1的次数。
bitsum = 00000000 00000000 00000000 00000000

2)将每个数字计入到bitsum[]中
10-> 00000000 00000000 00000000 00001010
4 -> 00000000 00000000 00000000 00001110
5 -> 00000000 00000000 00000000 00001211
5 -> 00000000 00000000 00000000 00001312
4 -> 00000000 00000000 00000000 00001412
4 -> 00000000 00000000 00000000 00001512
5 -> 00000000 00000000 00000000 00001613

3)bitsum的每一个元素对3取模:
bitsum = 00000000 00000000 00000000 00001010

4)将bitsum作为一个32bit的整数:
result = 00000000 00000000 00000000 00001010 = 10

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        
        // 遍历int类型的32个bit
        for(int i=0;i<32;i++)
        {
            int bitnums = 0;
            int bit = 1 << i;
            
            // 遍历整个数组,如果某个数字的某个bit上出现的数字不是0则累加
            for (auto num :nums)
            {
                if (num & bit)
                    bitnums++;
            }
                   
            // 如果某个bit上对3取余不为0,则是最终结果在这个bit上应该出现的数字
            if(bitnums % 3)
                ret  |= bit;
        }
        
        return ret;        
    }
};

python 题解

方法一

利用python中的set特性求集合中所有数据和的3倍再减去原数组中的数据之和,结果恰好为只出现一次数字的和之两倍:

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        
        numset = set(nums) 
        sumA = sum(numset) * 3
        sumB = sum(nums)
        
        return (sumA - sumB) >> 1

方法二

与 C++ 题解思路相同

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        res = 0
        for i in range(32):
            bitscount = 0
            for num in nums:
                bitscount += ((num>>i) & 1)
            if bitscount % 3!=0:
                res += (1<<i)
        return res if (res & (1<<31)) == 0 else res - (1<<32)

注意:

  • 最后对于正负数的处理需要特别注意。
posted @ 2019-03-17 14:22  youngliu91  阅读(296)  评论(0编辑  收藏  举报