文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>100题_34 找出数组中两个只出现一次的数字

100题_34 找出数组中两个只出现一次的数字

时间:2011-03-17  来源:小橋流水

个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。


可能大家都见识过找出一个只出现一次的数,直接把所有的数异或就可以了,最终的结果就是这个数了。但是如果出现两个这样的数,那又将如何呢?

 

假如这两个数为a和b,那么将所有的数异或得到的数必定为a^b。由于a和b不相等,那么a^b != 0,也就是说在a^b中必定至少有一位为1,对应位上a与b不一样,根据这一位,我们可以将a和b分开,并将数分成两组。注意,两个相同的数肯定会被分到同一个组。这样,分别对每一组进行取异或,就能求出这两个数了。

 

代码如下:

代码  1 /* 
 2  * File:   main.cpp
 3  * Author: ziqiao
 4  *
 5  * Created on 2011年3月17日, 下午12:05
 6  */
 7 
 8 #include <cstdlib>
 9 #include <iostream>
10 
11 using namespace std;
12 
13 int findOutOneOdd(int a[], int n)
14 {
15     int result = a[0];
16     for (int i = 1; i < n; i++)
17         result ^= a[i];
18     return result;
19 }
20 
21 void findOutTwoOdds(int a[], int n, int &odd1, int &odd2)
22 {
23     int x = findOutOneOdd(a, n);
24     int i;
25     for (i = 1; i != 0 ; i <<= 1)
26     {
27         if (x & i != 0)
28             break;
29     }
30     if (i == 0)
31         throw "input is illeagle";
32     bool flag1 = false,  flag2 = false;
33     for (int j = 0; j < n; j++)
34     {
35         if (a[j] & i != 0)
36         {
37             if (!flag1)
38             {
39                 odd1 = a[j];
40                 flag1 = true;
41             }
42             else
43              odd1 ^= a[j];
44         }
45         else
46         {
47             if (!flag2)
48             {
49                 odd2 = a[j];
50                 flag2 = true;
51             }
52             else
53                 odd2 ^= a[j];
54         }
55     }
56 }
57 
58 /*
59  * 
60  */
61 int main(int argc, char** argv)
62 {
63     int a[] = {4, 5, 3, 4, 5, 7, 7, 6, 8, 8};
64     int odd1, odd2;
65     findOutTwoOdds(a, 10, odd1, odd2);
66     cout << odd1 << " " << odd2  << endl;
67     return 0;
68 }

 

在写代码的时候,最好不要起一些容易混淆的变量名。我在编写该程序的时候,就范了该错误,调了好久才调好!

相关阅读 更多 +
排行榜 更多 +
打螺丝高手

打螺丝高手

模拟经营 下载
解救火柴人计划安卓版

解救火柴人计划安卓版

体育竞技 下载
鸡生化精英安卓版

鸡生化精英安卓版

飞行射击 下载