在数组中找出只出现一次的两个数

简介:

j_0020.gif来来来,看一道面试题!!!


题目是这样叙述的:

         在一个数组中除两个数字只出现1次外,其它数字都出现了2次, 要求尽快找出这两个数字。

         要求:时间复杂度为O(N),空间复杂度为O(1)。

j_0012.gif这该怎么解决呢???

          请看我的分析:


将这道题简单化:

    一个数组中只有一个数字出现一次,其他数字都是成对出现的,这时我们可以根据异或运算符的特性:A^B^A = B; 0 ^ A = A;我们可以将这个数组的全部元素依次做异或运算,最终结果就是那个只出现一次的数字。


    如果这个数组中出现两个不同的数字,而其他数字均出现两次,假设这两个数字分别是x, y。那如果可以将x, y分离到两个数组。这时这道题就变成两个我们简化之后的版本中的数组了。这样问题就可以得到解决了。由于x,y肯定是不相等的,因此在二进制上必定至少有一位是不同的。根据这一位是0还是1可以将x,y分开到A组和B组。并且数组中其他元素也可以根据这个方法划分到两个数组中。这时将两个数组分别做异或运算,结果就是这两个数字。


y_0034.gif下面就看我实现的例子吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void  FindNums( int  a[],  int  n,  int * num1,  int * num2) //a[]一维数组;n是数组中的元素个数;
{                                          //num1和num2分别要保存两个只出现一次的数字
     int  tmp = 0;
     for  ( int  i = 0; i < n; i++)
     {
         tmp ^= a[i];
     }
     int  j = 0;
     for  (j; j <  sizeof ( int )* 8; j++)
     {
         if  ((tmp >> j) & 1 == 1)
             break ;
     }
     
     num1 = 0;
     num2 = 0;
     for  ( int  i = 0; i < n; i++)
     {
         if  ((a[i] >> j) & 1 == 1)
         {
             *num1 ^= a[i];
         }
         else
         {
             *num2 ^= a[i];
         }
     }
}


t_0016.gif恩,问题解决了


本文转自 七十七快 51CTO博客,原文链接:http://blog.51cto.com/10324228/1787589


相关文章
|
6月前
|
算法
把数组里面数值排成最小的数
把数组里面数值排成最小的数
20 1
|
9天前
|
存储 算法 索引
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数
|
3月前
|
Python
计算小于或等于n的非负整数区间包含的1的数量
计算小于或等于n的非负整数区间包含的1的数量
21 0
|
4月前
不用数组求多个数的最小值
不用数组求多个数的最小值
16 0
非负数组中两个数相与的最大结果
非负数组中两个数相与的最大结果
Java数组中找出两个相加等于某个值的数据下标
Java数组中找出两个相加等于某个值的数据下标
Java数组中找出两个相加等于某个值的数据下标
|
Java
Java基础—给定一个数组—输出数组中最大值_最大值下标—最小值_最小值下标
在数组中有三种情况,数组中全是正数,数组中全是负数,数组中有正数和负数。那么根据这个情况本文介绍在三种情况下用来实现输出数组中最大值、最大值下标、最小值、最小值下标的Java代码。
3308 0
一个数组中有两种数出现了奇数次,其它数都出现了偶数次,怎么找到并打印这两种数
一个数组中有两种数出现了奇数次,其它数都出现了偶数次,怎么找到并打印这两种数
一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数