微软面试题--找数组中唯一出现两次的数

来源:互联网 发布:邮箱服务器端口 编辑:程序博客网 时间:2024/05/22 16:58

微软面试题--找数组中唯一出现两次的数  


2012-09-03 10:44:43|  分类: 算法、数据结构 |  标签:算法数据结构  面试   |举报|字号 订阅
题:假设你有一个用1001个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1到1000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。


方法一、若使用辅助的存储方式,该选择何种存储方式呢?可使用hash的存储方式,以1到1000作为hash表的索引,遍历原数组,统计各数字出现的个数并存储到以该数字为索引值的hash表中,若某个hash[x]的值为2则退出循环,x就是重复出


int hash[1001];
int findRepeatNum(int a[])
{
 int repeat_num;
 for(int i = 0; i < 1001; i++)
 {
  if(a[i] = hash[a[i]])
  {
   repeat_num = a[i];
   break;
  }
  else
   hash[a[i]] = a[i];
  return repeat_num;
 }
}


方法二、既然这1001个数中只有一个数是重复的。那我们其实可以用求和法。先用求和公式求出1--1000的和。然后求出实际这1001个数的和,两者之差就是重复的那个数。但是这种方法只适用于只有一个数是重复的情况。
int findRepeatNum(int a[])
{
 int s1,s2;
 s1 = (1 + 1000)*1000/2;
 for(int i = 0; i < 1002; i++)
  s2 += a[i];
 return s2 - s1;
}
方法三:异或法


数组a[N]中的N个数异或结果与1至N-1异或的结果再做异或,得到的值即为所求。


设重复数为A,其余N-2个数异或结果为B。
N个数异或结果为A^A^B
1至N-1异或结果为A^B
由于异或满足交换律和结合律,且X^X = 0  0^X = X;
则有
(A^B)^(A^A^B)=A^B^B=A


问题扩展:现在将问题扩展成为这1001个数里,每个数的大小范围是[1,1000],并且至少有一对数是重复的(以前是只有一对),需求是求出第一对重复的数。显然,方法二和方法三是行不通的了。
扩展方法:先将这1001个数看成是1001个槽,每个槽中的数字范围是[1,1000],那么从第一个槽开始,假设第一个槽中的数字为10,那么则把第一个槽中的数字置为一个特殊值END,然后去查看槽10中的数字,如果槽10中的数字是10,那么10就是第一个重复的数字,如果槽10的数字不是10,那么则继续遍历下去。
0 0
原创粉丝点击