剑指offer——面试题40:数组中只出现一次的数字

题目:

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

思路:

(1)首先考虑数组中若是只有一个数字是出现一次,其他都是出现两次的情况,在这种情况下,将所有的

数字都位异或运算(^),因为相同的数字异或结果为0,所以最后地到的结果就是那个出现一次的数。

(2)下面考虑本题出现有两个出现一次,其他的都是出现一次,这种情况下,可以将所有的异或一遍,

那么最后得到的结果为这两个出现一次的数的异或的结果。

然后找到这个数的从右为0数起的第一个不为0的位,这样可以根据这个位将这个数组分成两部分,一部分

这个第n位为0,一部分这个第n位为1.

然后再分别异或,最后得到的两个结果就是了。

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4
 5 //找到这个数的右起第几位不为0.
 6 int number_of_first_one(unsigned int a)
 7 {
 8     int re=0;
 9     for(int i=0;i<32;i++)
10     {
11         if((a&(1<<i))!=0)
12         {re=i;break;}
13     }
14     return re;
15 }
16
17 //判断右起第n位是否为1
18 bool ifone(unsigned int a,int n)
19 {
20     if(a&(1<<n))
21         return 1;
22     else
23         return 0;
24 }
25
26 //主函数。
27 void find_number(vector<int>& vec,int *num1,int *num2)
28 {
29     if(vec.empty())
30         return;
31     int len=vec.size();
32     if(len<=1)
33         return;
34
35     unsigned int a=vec[0];
36     for(int i=1;i<len;i++)
37         a^=vec[i];
38
39     int n=number_of_first_one(a);
40     *num1=0;
41     *num2=0;
42     for(int i=0;i<len;i++)
43     {
44         if(ifone(vec[i],n))
45             *num1^=vec[i];
46         else
47             *num2^=vec[i];
48     }
49 }
50 int main()
51 {
52     int ary[8]={2,4,3,6,3,2,5,5};
53     vector<int> vec(ary,ary+8);
54     int num1;
55     int num2;
56     find_number(vec,&num1,&num2);
57     cout<<num1<<endl;
58     cout<<num2<<endl;
59     system("pause");
60 }
时间: 2024-09-27 04:27:12

剑指offer——面试题40:数组中只出现一次的数字的相关文章

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

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

剑指offer 面试题40—数组中两个只出现一次的数字

题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度O(n),空间复杂度O(1). 基本思想: http://blog.csdn.net/wtyvhreal/article/details/44260321 #include <iostream> using namespace std; int Find1(int n)//从低位开始找第一个1的位置 { int index=0; while((n&1)==0 &&a

剑指offer 面试题36—数组中的逆序对

题目: 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数.例如在数组{7,5,6,4}中一共存在5对逆序对,分别是(7,6),(7,5),(7,4),(6,4),(5,4) 基本思想: 解法一:O(n^2) 最简单的想法就是遍历每一个元素,让其与后面的元素对比,如果大于则count++,但是这样的时间复杂度是O(n^2). 解法二:O(nlogn) 归并排序思路: 例如7,5,4,6可以划分为两段7,5和4,6两个子数组 1

[剑指Offer]40.数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 我们直到异或的性质: 任何一个数字异或他自己都等于0. 所以说我们如果从头到尾依次异或每一个数字,那么最终的结果刚好只出现一次的数字,因为成对出现的两次的数字全部在异或中抵消了. 这道题中有两个数字只出现一次.这样的话我们得到的结果就是这两个数字的异或结果.因此我们想办法把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字.这样我们就可以对这两个子数组分别异或,就能得到两个只出现一

【剑指offer】Q29:数组中出现次数超过一半的数字

就本题而言,个人觉得练习下partition函数是有必要的,毕竟它是快速排序的核心,是基础性的东西,也是必须要掌握的,至于书中给出的"取巧"性解法,是属于个人思维能力的考察,是一种考虑问题的思路,不是一两个问题就能练就的. partition函数,包括快速排序,是一定要信手拈来的,必须的. import random def MoreThanHalf(array): if len(array) == 0: return 0 start = 0 end = len(array) - 1

【剑指offer】二维数组中的查找

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 分析: 首先选择数组中右上角的数字.如果该数字等于要查找的数字,查找过程结束:如果该数字大于要查找的数字,剔除这个数字所在的列:如果该数字小于要查找的数字,剔除这个数字所在的行.依次类推,直到查找范围为空. 示例程序: #include <stdio.h> #include <stdlib.h> int

剑指OFFER之二维数组中的查找(九度OJ1384)

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数. 输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字. 接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每

【剑指offer】Q40:数组中出现一次的数字

按着书里面讲述的方法,根据某一位来将整个数组拆分成两个部分,取每一部分中出现一次的数.书中的处理略显复杂,这里简化下分类的方法. def once(array): reOR = 0 for x in array: reOR ^= x bit1 = firstBit1(reOR) first = 0 second = 0 for x in array: if x & bit1 != 0: first ^= x else: second ^= x return first, second def f

【剑指offer】Q40:数组中出现一次的数

书里面关于分类的判断有些麻烦,通过某一位为0为1来对数组元素进行分类.假如第3位为1,那么也就是元素x & 8 等于或不等于0,所以没必要非的用第几位去判断. def once(array): reOR = 0 for x in array: reOR ^= x bit1 = firstBit1(reOR) first = 0 second = 0 for x in array: if x & bit1 != 0: first ^= x else: second ^= x return f

剑指Offer面试题40(Java版):数组出现一次的数字

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次. * 请些程序找出这两个只出现一次的数字.要求时间复杂度为O(n),空间复杂度为O(1) 例如输入数组{2,4,3,6,3,2,5,5},因为只有4,6这两个数字只出现一次,其他数字都出现了两次,所以输出4,6 这是一个比较难的题目,很少有人在面试的时候不需要提示一下子想到最好的解决办法.一般当应聘者想了几分钟那个后还没有思路,面试官会给出一些提示. 我们想到异或运算的一个性质:任何一个数字异或它自己都等于0,也就是说,如果我们从头到