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?
int singleNumber(int A[], int n) {
for(int i = 0; i < n; i++)
{
if(count(A, A + n, A[i])<2)
return i;
}
}
然后搜肠刮肚想想那个算法可以优化为时间O(n)的复杂度的?分治?减治?贪心?动态规划???想多了。
1. 要求复杂度为O(n),白话点说也就是不能在一个n次循环里面添加任何循环,前面之所以失败就是因为这个原因。但是可以在循环外添加循环!!!
2. 既然可以在查找循环外添加循环,那么添加什么循环好呢?排序吧,没错!排序的数列干什么都方便!(感觉这个结论也适用很多地方)
排序之后就可以很方便地计算一个数在数列中出现了多少次了。一连出现多少次就是总共出现多少次了,方便吧。O(∩_∩)O~
1. 如果数列外空呢?
2 如果第一个是single number呢?
3 如果最后一个是single number呢?
//通用性好,适合两种情况
int singleNumber(int A[], int n) {
//特殊情况1,2
if(n<=0) return -1;
if(n==1) return A[0];
sort(A, A + n);
int j = 1;
for(int i = 0; i < n - 1; i++)
{
if(A[i] == A[i+1])
j++;
else
{
if(j<2) return A[i];//这里修改为j<3那么就可以适用于single number II了。
j = 1;
}
}
//特殊情况3 最后一个是single number的特殊情况
return A[n-1];
}
//2014-2-18 update
int singleNumber(int A[], int n)
{
unordered_map 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;
}
下面是Single number I 的位运算解法,思路就是每位bit出现2次就清零,所以可以不断异或运算得出最终结果:
//2014-2-18_2 update
int singleNumber(int A[], int n)
{
int ans = 0;
for (int i = 0; i < n; i++) ans ^= A[i];
return ans;
}
Single number II 的位运算两种解法-- 参考leetcode论坛的代码:
方法一,int的32个bit逐个处理-这个方法还算简单的了:
int singleNumberII_36(int A[], int n)
{
int ans = 0;
for (int i = 0; i < 32; i++)
{
int c = 0, d = 1<
方法二,进位,掩码清零法-本方法还是挺难理解的,要很小心,否则,很容易出错的,对位运算不熟悉是很难写出来的。
int singleNumber(int A[], int n)
{
int one = 0, two = 0;
for (int i = 0; i < n; i++)
{
two |= A[i] & one;//two 积累值
one ^= A[i];//one不断求反
int t = one & two;//第三次的时候one和two都保留了该位的值
one &= ~t;//清零出现三次的该位的值
two &= ~t;
}
return one;
}
不过上面的位运算方法一还是算好理解的了,而且也比较容易就可以用在其他情况,比如所有numbers都出现5次其中一个除外,面试的时候我觉得应该是首推算法吧。