查找未重复出现数一系列问题

来源:互联网 发布:painter mac 2017 破解 编辑:程序博客网 时间:2024/06/06 08:56

今天来说一说从一个数组中查找没有重复出现的数几个一系列问题:

第一道题:

给你一个数组,其中只有一个数出现过一次,其它数均出现了两次,请你找出这个只出现过一次的数。

要是没什么出奇想法的话可能就会想到直接两个for循环嵌套去遍历这个数组了,但是这样效率未免有点低了。这里其实可以利用逻辑运算来实现。

我们都知道两个相同的数异或为0,其实还有0异或两个相同的数,结果依旧为0;再改一下,让0异或三个数,其中有两个是相同的,结果显而易见,我们会得到第三个数,那个不同的数。所以这道题就迎刃而解了:

int i = 0, rs = 0;int arr[] = { 1, 3, 1, 5, 3, 6, 5, 4, 4};for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){rs ^= arr[i];}
现在还有一道题:

一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。找出这两个数字。

怎么解?

其实思路也不难,先按照上一道题的思想,让0不断与数组中的元素异或,我们得到的肯定是那两个不同的数的异或结果!现在的关键就是如何将两个数给分开?

进一步想想,其实只需要从异或的结果任意找一个1,根据这一位我们把数组中的数分为两拨:首先,相同的数肯定在同一拨;其次,那两个不同的数这一位是不同的,所以他们被分别放在了两拨里,于是就这么轻而易举的分开了,这两拨数分别都只有一个只出现一次的数,其它均出现两次。这时,这个问题就转换成了两个上一道题!

具体算法如下:

/*  * 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 * 找出这两个数字,编程实现 */#include <stdio.h>int main(){int xor = 0, and = 0, num1 = 0, num2 = 0;int i = 0, digth = 0;int arr[] = {1, 3, 5, 4, 3, 6, 5, 1, 7, 6};int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < sz; i++){xor ^= arr[i];}for (digth = 0; digth < sizeof(int); digth++)//找出一个可以区分两个不同数的位{if (((xor >> digth) & 1) == 1)break;}for (i = 0; i < sz; i++){if (((arr[i] >> digth) & 1) == 1)//把那一位不同的数分为两拨num1 ^= arr[i];elsenum2 ^= arr[i];}printf("%d, %d\n", num1, num2);return 0;}
有什么没讲清楚的或不明白的欢迎在评论区和我交流微笑

1 0
原创粉丝点击