LeetCode OJ 之 Single Number II (唯一的数字 - 二)

题目:

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?

给一个整型数组,每个元素都出现了三次,但是有一个例外,找出这个例外的数。

注意:

算法要有线性时间复杂度。能做到不适用额外的内存吗?

思路:

本题依然使用位运算。首先思考,计算机是怎么存储数字的。即二进制,考虑把一个整数表示成32位的二进制数,定义一个32个数的数组,保存某个整数二进制形式的第i位,比如说十进制数10,二进制形式是00000000 00000000 00000000 00001010,如果这个数出现三次,把它们对应的第i位的和存储到数组中。如果是3的倍数,说明这个数出现了3次。比如说出现了3次10,那么结果就是0000000000000000 00000000 00003030。如果对所有的数的第i为求和并保存到数组中,再对数组中的所有数 % 3 ,那么最后数组中的数就是只出现一次的数的二进制位。

代码:

class Solution {
public:
    int singleNumber(int A[], int n)
    {
        int result = 0 ;
        int count[32] = {0};
        for(int i = 0 ; i < 32 ; i++)
        {
            for(int j = 0 ; j < n ; j++)
            {
                //把所有数的二进制形式的第i位取出来((A[j] >> i) & 1)并求和
                count[i] += (A[j] >> i) & 1;
            }
            count[i] %= 3;
        }
        for(int i = 0 ; i < 32 ; i++)
        {
            result += (count[i] << i);
        }
        return result;
    }
};

这个算法是有改进的空间的,可以使用掩码变量:

ones    代表第i th 位出现一次的掩码变量

twos   代表第i th 位出现两次的掩码变量

threes   代表第i th 位出现三次的掩码变量

假设在数组的开头连续出现3次5,则变化如下:

ones = 101

twos = 0

threes = 0

--------------

ones = 0

twos = 101

threes = 0

--------------

ones = 0

twos = 0

threes = 101

--------------

class Solution {
public:
    int singleNumber(int A[], int n)
    {
      int ones = 0, twos = 0, threes = 0;
      for (int i = 0; i < n; i++) 
      {
            twos |= ones & A[i];//出现1次的结果再与A[i] 取与的结果就是出现2次的结果
            ones ^= A[i];// 出现一次的结果
            //对于ones 和 twos 把出现了3次的位置设置为0
        	//如果ones和twos中的一个为0,则three为0
            threes = ones & twos;
            ones &= ~threes;
            twos &= ~threes;
      }
      return ones;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值