您的位置:首页 > 其它

leetcode(137)数组之Single Number II

2017-04-18 15:14 441 查看
题目】
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?

【题意】
给定一个整数数组,每个元素出现了三次,除了一个。找出那个出现一次的数字。
注意:
你的算法应该在一个线性时间复杂度完成。你能不能无需使用额外的内存来完成它?

方法一:hash表,但 需要O(n)的额外空间;

//方法一:hash表,时间复杂度是O(n),空间复杂度是O(n);

int singleNumber(vector<int>&nums)
{
map<int,int>count;
auto index=nums.begin();
for(auto it=nums.begin();it!=nums.end();++it)
{
count[*it]++;
}
for(auto it=nums.begin();it!=nums.end();++it)
{
if(count[*it]==1)
{
index=it;
break;
}
}
return *index;
}

方法二:位运算 ;这是一个通用的解法,如果把出现3次改为 k 次,那么只需模k就行了。

//方法二:所有的数用二进制表示,我们把每个数的第i 位取和之后再对3取余,那么只会有两个结果 0 或 1 。
//如果为0代表只出现一次的那个数第i位也为0,如果为1表示只出现一次的那个数第i位也为1。
//因此取余的结果就是那个 “Single Number”。
//时间复杂度 O(n),空间复杂度 O(1);
int singleNumber(vector<int>&nums)
{
const int W=sizeof(int)*8  //一个整数的bit数,即一个数的字长;
int count[W]={0};            //count[i]表示在第i位出现的次数;
int result=0;
for(int i=0;i<W;i++)
{
for(int j=0;j<nums.size();j++)
{
if((nums[j]>>i&1))
count[i]++;
}
result|=((count[i]%3)<<i)  //这是一个通用的解法,如果把出现3次改为 k 次,那么只需模k就行了。
}
return result;
}

方法三:可以使用掩码变量
方法 2:用 ones 记录到当前处理的元素为止,二进制 1 出现“1 次”(mod 3 之后的 1)的有哪些二进制位;
用 twos 记录到当前计算的变量为止,二进制 1 出现“2 次”(mod 3 之后的 2)的有哪些二进制位。
当 ones 和 twos 中的某一位同时为 1 时表示该二进制位上 1 出现了 3 次,此时需要清零。
即用二进制模拟三进制运算。最终 ones 记录的是最终结果。
即:
ones   代表第ith 位只出现一次的掩码变量
twos  代表第ith 位只出现两次次的掩码变量
threes  代表第ith 位只出现三次的掩码变量

class Solution {
public:
int singleNumber(int A[], int n) {
int one=0;
int two=0;
int i,j,k;
for(i=0; i<n; i++)
{
two = two |(one&A[i]);
one = one^A[i];

int three = two&one;
two = two^three;
one = one^three;
}

return one|two;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: