Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
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?
三种解法:
1.排序
2.unsorted map
3.位运算
一、排序
题一中,排序后,single one 一定出现在A[2 * k]处,线性检查一遍即可。题二类推。
class Solution {
public:
int singleNumber(int A[], int n) {
if (n <= 1)
return A[0];
sort(A, A + n);
for (int i = 0; i < n; i += 2)
if (A[i] != A[i + 1])
return A[i];
}
};
二、unsorted map
网上查到的,在map中记录是否出现过。在第n次删去(题一中n=2,题二中n=3),最后留下的就是single one。
引用:
c++11引入的散列容器,散列容器具有不稳定性:他依赖于实际所使用的散列算法。而针对不同的元素数量,不同的散列算法具有相当大的性能差异。
所以,理论上(同样是理论上)他们的算法时间复杂度是近乎“常量”(如果要处理冲突那就不是了)。但时间上对于一般用户使用起来可能会带来风险。
方法:
//2014-2-18 update
int singleNumber(int A[], int n)
{
unordered_map<int, bool> ump_ii;
for (int i = 0; i < n; i++)
{
if (!ump_ii.count(A[i])) ump_ii[A[i]] = true;
else ump_ii.erase(A[i]);
}
return ump_ii.begin()->first;
}
三、位运算
同样是从网上找到的。题一有特殊解法,即每个数xor一遍即可。通用解法是,n表示重复次数,对于32位int,计算每一位上增加过k个1,若k % n == 1则single one 在这一位上为1,所以答案上置为1。
int singleNumberII_36(int A[], int n)
{
int ans = 0;
for (int i = 0; i < 32; i++)
{
int c = 0, d = 1<<i;
for (int j = 0; j < n; j++)
if (A[j] & d) c++;
if (c%3) ans |= d;
}
return ans;
}