数组中只出现一次的两个数字

题目:给定一个整型数组,其中有两个数字只出现一次,其余的数字都出现两次,找出这两个只出现一次的数字.时间复杂度为O(n),空间复杂度为O(1).

异或运算的特性:相等的两个整数异或的结果为0;一个整数与0进行异或运算的结果为其本身.

基本思想:将这两个只出现一次的数字分到两个数组中,这样就很容易找到只出现一次的数字.

采用上述思想需要解决的问题:

1.如何才能保证两个只出现一次的数字分别位于两个数组?

2.空间复杂度为O(1),需要在原数组上进行分割操作,这个如何做到?

解决办法:

1.将数组中的所有数字进行异或运算,得到一个非零值.然后找出这个非零值的二进制形式中1第一次出现的位置.根据得到的这个位置的值是否为1将数组分成两个部分.可以得知,两个只出现一次的数字将被分到不同的部分.

2.快速排序的patition函数可以很好地解决这个问题.以某一标准将数组分成两个不同的部分.

代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4
 5 void get_num(int *, int);
 6 void swap(int *, int *);
 7
 8 int main(int argc, char *argv[])
 9 {
10     int a[14] = {1, 2, 5, 1, 5, 2, 16, 20, 23, 20, 16, 30, 23, 6};
11     int result = 0;
12
13     get_num(a, sizeof(a)/sizeof(int));
14
15     return 0;
16 }
17
18 void get_num(int *a, int len)
19 {
20     int result = 0;
21     int result1 = 0;
22     int result2 = 0;
23     int m = 0;
24     int i = 0;
25     int j = 0;
26     int p = 0;
27
28     for (i=0; i<len; i++)
29     {
30         printf("%d ", *(a + i));
31         result = *(a + i) ^ result;
32     }
33     printf("\n");
34
35     while (m < 32)
36     {
37         if (result % 2 != 0)
38         {
39             break;
40         }
41
42         result = result >> 1;
43         m++;
44     }
45     printf("m = %d\n", m);
46     i = -1;
47     j = 0;
48     for (j=0; j<len; j++)
49     {
50         if ((*(a + j) >> m) % 2 != 0)
51         {
52             swap((a + i + 1), (a + j));
53             i++;
54         }
55     }
56
57     p = i;
58     for (i=0; i<=p; i++)
59     {
60         printf("%d ", *(a + i));
61         result1 = *(a + i) ^ result1;
62     }
63     printf("\n");
64
65     for (i=p+1; i<len; i++)
66     {
67         printf("%d ", *(a + i));
68         result2 = *(a + i) ^ result2;
69     }
70     printf("\n");
71
72     printf("%d  %d\n", result1, result2);
73
74 }
75
76
77 void swap(int *a, int *b)
78 {
79     int temp;
80     temp = *a;
81     *a = *b;
82     *b = temp;
83 }

时间: 2024-10-27 14:09:46

数组中只出现一次的两个数字的相关文章

73. 数组中只出现一次的两个数字

异或运算,看视频吧.AcWing 73. 数组中只出现一次的两个数字 https://www.acwing.com/solution/acwing/content/1324/ 假设这2个数为x,y 1.对所有数进行异或,相同的2个数执行异或后的值为0.结果就是x⊕y. 2.异或运算的性质:.若a是二进制数0101,b是二进制数1011:则a⊕b=1110 ,只有在两个比较的位不同时其结果是1,否则结果为0. 可以肯定的是,x⊕y的结果有某一位k是1.利用第k位是1,将数组分成2类数组,数组m是Z

《剑指offer》第五十六题I:数组中只出现一次的两个数字

// 面试题56(一):数组中只出现一次的两个数字 // 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序 // 找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). #include <cstdio> unsigned int FindFirstBitIs1(int num); bool IsBit1(int num, unsigned int indexBit); void FindNumsAppearOnce(int data[], int

剑指Offer 面试题40:数组中只出现一次的两个数 题解

面试题40:数组中只出现一次的两个数 提交网址:  http://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193 或 http://ac.jobdu.com/problem.php?pid=1351 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 牛客网OJ的输入输出接口是:void Fin

C++找数组中只出现一次的两个数并保存(牛客剑指offer)

//////////////////////////////////// //一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. //心得:开始我以为是只出现一次的一个数,题中确是有2个只出现一次的数 //数组从i=0,开始,另一个j=i+1开始,当出现一个相等的我就把它保存在我新建的数组里面b[n/2+1], //当j==n时,说明在i位置之后没有跟a[i]相等的数值了,但是不能保证前面没有, //于是这里我保存在b数组里面的数据就起作用了,再遍历一遍

剑指Offer39 数组中寻找和为sum的两个数字

1 /************************************************************************* 2 > File Name: 39_TwoNumbersWithSum.cpp 3 > Author: Juntaran 4 > Mail: [email protected] 5 > Created Time: 2016年09月03日 星期六 11时14分49秒 6 *******************************

【白话经典算法系列之十七】 数组中只出现一次的数 其他三次

本文地址:http://blog.csdn.net/morewindows/article/details/12684497转载请标明出处,谢谢. 欢迎关注微博:http://weibo.com/MoreWindows 首先看看题目要求: 数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次.请给出最快的方法找到x. 这个题目非常有意思,在本人博客中有<位操作基础篇之位操作全面总结>这篇文章介绍了使用位操作的异或来解决——数组中其他数字出现二次,而x出现一次,找出x.有<

数组中只出现一次的字符

题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组大小.2<=n <= 10^6. 第二行包含n个整数,表示数组元素,元素均为int. 输出: 对应每个测试案例,输出数组中只出现一次的两个数.输出的数字从小到大的顺序. 样例输入: 8 2 4 3 6 3 2 5 5 样例输出: 4 6 思路: 设a.b仅出现一次. 1.假如数组中只有一个数字出现一次,其他数字均出现两次.我们可

剑指offer系列源码-数组中只出现一次的数字

题目1351:数组中只出现一次的数字 时间限制:1 秒内存限制:32 兆特殊判题:否提交:2582解决:758 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组大小.2<=n <= 10^6. 第二行包含n个整数,表示数组元素,元素均为int. 输出: 对应每个测试案例,输出数组中只出现一次的两个数.输出的数字从小到大的顺序. 样例输入: 8 2 4 3 6 3 2 5 5

【剑指offer】数组中只出现一次的数字(1)

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组大小.2<=n <= 10^6. 第二行包含n个整数,表示数组元素,元素均为int. 输出: 对应每个测试案例,输出数组中只出现一次的两个数.输出的数字从小到大的顺序. 样例输入: 8 2 4 3 6 3