标签:
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