标签:
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?
之前做过了数组中其他数出现两次,仅有一个出现一次的,直接用所有元素异或就行了(只要是偶数次,都可以用这个方法),本题变为其他元素出现3次,而且时间复杂度要求线性,空间为常数。
方法一:
同Single Number方法一样,删除数组中重复出现的数字,输出最后剩下的或者没有重复的数字即可http://blog.csdn.net/sinat_24520925/article/details/45576735
代码如下:
class Solution {
public:
int singleNumber(vector<int>& nums) {
if(nums.size()==1) return nums[0];
while(nums.size()>1)
{
int temp=nums[0];
int flag=0;
for (int i=1;i<nums.size();i++)
{
if (nums[i]==temp)
{
nums.erase(nums.begin()+i);
if (flag==1)
{
nums.erase(nums.begin());
break;
}
flag++;
i--;
}
}
if (!flag)
{
return nums[0];
}
}
return nums[0];
}
};int 数据共有32位,可以用32变量存储 这 N 个元素中各个二进制位上 1 出现的次数,最后 在进行 模三 操作,如果为1,那说明这一位是要找元素二进制表示中为 1 的那一位。
例如:A[]={2,3,4,3,2,2,3}
0010
0011
0100
0011
0010
0010
0011
= -0-1-6-3-(1的个数)
0100
代码如下:
int bitflag[32]={0};
int res=0;
for (int i=0;i<32;i++)
{
for (int j=0;j<nums.size();j++)
{
bitflag[i]+=(nums[j]>>i)&1;
}
res|=(bitflag[i]%3)<<i;
}
return res;
这是一个更快一些的解法,利用三个变量分别保存各个二进制位上
1 出现一次、两次、三次的分布情况,最后只需返回变量一就行了。代码如下:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int one=0,two=0,three=0;
for (int i=0;i<nums.size();i++)
{
two|=one&nums[i];
one=one^nums[i];
three=one&two;
one=one&(~three);
two=two&(~three);
}
return one;
}
};方法二时间复杂度为O(32*n),是线性的,且是通用的,当数组中的重复元素变为r的时候,模r即可;
方法三比方法二快,时间复杂度为O(n),但是不是通用的,且理解起来有点难度。
标签:
原文地址:http://blog.csdn.net/sinat_24520925/article/details/45646675