700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 数据结构面试题总结5----数组:找出数组中唯一一个出现一次的元素

数据结构面试题总结5----数组:找出数组中唯一一个出现一次的元素

时间:2019-05-08 11:58:25

相关推荐

数据结构面试题总结5----数组:找出数组中唯一一个出现一次的元素

问题描述:一个数组其中有一个元素出现了一次(奇次),其他元素都出现两次(偶数次数),找出出现一次(奇次)的元素。

分析:碰到这种偶次奇次的问题,首先要想一下位运算中的异或。一个数异或本身为0,一个数异或0不变。a ^ a = 0, a ^ 0 = a。

这个题中,我们可以把所有的数一起求异或,那剩下的肯定就是出现一次的元素了。

int FindOnly(int *a, int n){ int onlyNum = a[0]; for(int i = 1; i < n; i++) { onlyNum = onlyNum ^ a[i]; } return onlyNum;}

问题变种:一个数组其中有两个元素出现了一次(奇次),其他元素都出现两次(偶数次数),找出出现一次(奇次)的元素。

此篇帖子里有详细描述,我并没有找到原文,他也是转的:/wangwh485/article/details/6715357

分析:因为有两个元素了,他俩异或运算后的结果根本无法分辨出是哪两个数,但是他俩异或的结果却可以让我们把他俩分开。

我们根据这个结果的最后为1的位,来把原数组分成两个数组(此位为0的一组,此位为1的一组,这样两个出现一次(奇次)就被分到两个数组中了),再分别对这两个数组用第一个问题的方法。

我这里就直接引用上面帖子中的代码了:

int getSingle(int *a, int n) //获取全部元素的异或结果 { if(!a) return -1; int sum = a[0] ; for(int i = 1; i < n; i++) sum ^= a[i] ; return sum ; }void getTwo(int *a ,int & one, int & two, int sum, int n) //求数组中两个不同的元素 { unsigned int flag = 1; while(flag) //求异或结果,最低的为1的二进制位,根据此位是否为1,将元素分为两组,两个不同的元素,在此位必然,一个为1,一个为0 { if(flag&sum) break; flag = flag << 1 ; } //下面将flag与每个元素相求与,根绝结果是否为1,将其化为两个数组 //分别计算每个数组的异或结果,并将结果,存储分别存储在one和two中。 one = two = 0 ;//0与任何数异或都为其自身,所以初始化的时候,应该初始化为0 for(int i = 0 ; i < n ;i++ ) { if(a[i] & flag) { one ^= a[i] ; } else { two ^= a[i] ; } }}int main(){ int a[] = {3 , 5 ,8 , 8 , 5 , 3 ,1 ,4 ,4,10} ; int single = getSingle(a,10) ; int one = 0 ; int two = 0; getTwo(a ,one , two ,single,10) ; cout<<single<<" "<<one<<" "<<two<<endl ; system("pause") ; return 0 ; }

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。