一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
来源:互联网 发布:office2011for mac 编辑:程序博客网 时间:2024/05/28 06:04
一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字。
二 问题分析
此题实际考察了,对位操作的理解。首先进行简化,考虑只有一个数组中,只存在出现了一次的一个数字,其余数字在数组中出现两次,试
找出这个数字。
三 解决方案
首先 回忆 异或操作,任意数字与自身相异或,结果都为0.
还有一个重要的性质,即任何元素与0相异或,结果都为元素自身。
得到一个数字的某一位:第0位:a&1;第1位:a&(1<<1)...
特别注意:在判断a&b是否为0时,这样写是不对的:if(a&b==0)。因为==的优先级高于&,相当于a&(b==0)。而应该写成:if( (a&b)==0 ) 或if(!(a&b))
1 从数组的起始位置开始,对元素执行异或操作,则最后的结果,即为此只出现了一次的元素。
2 题目中,数组中存在两个不同的元素,若是能仿造上述的解决方案,将两个元素分别放置在两个数组中,然后分别对每个数组进行异或操作,
则所求异或结果即为所求。
3 首先对原数组进行全部元素的异或,得到一个必然不为0的结果,然后判断该结果的2进制数字中,为1的最低的一位。
然后根据此位是否为1 ,可以把原数组分为两组。则两个不同的元素,必然分别在这两个数组中。
4 然后对两个数组,进行异或操作,即可得到所求。
四 代码示例
#include <iostream>
using namespace std ;
const int N = 10 ;
int getSingle(int * a) //获取全部元素的异或结果
{
if(!a)
return -1;
int sum = a[0] ;
for(int i = 1; i < N; i++)
sum ^= a[i] ;
return sum ;
}
int getTwo(int * a ,int & one , int & two , int sum) //求数组中两个不同的元素
{
unsigned int flag = 1;
while(flag) //求异或结果,最低的为1的二进制位,根据此位是否为1,将元素分为两组,两个不同的元素,在此位必然,一个为1,一个为0
{
if(flag&sum)
break;
flag = flag << 1 ;
}
//下面将flag与每个元素相求与,根绝结果是否为1,将其化为两个数组
//分别计算每个数组的异或结果,并将结果,存储分别存储在one和two中。
one = two = 0 ;//0与任何数异或都为其自身,所以初始化的时候,应该初始化为0
for(int i = 0 ; i < N ;i++ )
{
if(a[i] & flag)
{
one ^= a[i] ;
}
else
{
two ^= a[i] ;
}
}
}
int main()
{
int a[N] = {3 , 5 ,8 , 8 , 5 , 3 ,1 ,4 ,4,10} ;
int single = getSingle(a) ;
int one = 0 ;
int two = 0;
getTwo(a ,one , two ,single) ;
cout<<single<<" "<<one<<" "<<two<<endl ;
system("pause") ;
return 0 ;
}
#include <iostream>using namespace std;int find_1(int a[],int n){int b=a[0];for(int i=1;i<n;i++){b=b^a[i];}return b;}void find_2(int a[],int n){int one=0,two=0;int b=find_1(a,n);int flag=1;//000001 从后向前找 哪一位为1 while(1){if((b&flag)!=0)break;flag=flag<<1;}for(int i=0;i<n;i++){if(a[i]&flag){one=one^a[i];}else{two=two^a[i];}}cout<<endl<<one<<' '<<two<<endl;}void main(){int a[]={11,4,11,2,1,5,2,4,9,5};int n=sizeof(a)/4;find_2(a,n);system("pause");}
- 一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n), 空间复杂度是O(1)
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 如何快速找出一个数组中只出现一次的两个数,其他元素出现两次?保证时间复杂度O(n),空间复杂度O(1)
- 找出一个数组中出现次数超过一半的那个数字,要求时间复杂度O(n)和空间复杂度为O(1)。
- 数组中只出现一次的数字,时间复杂度O(n),空间复杂度O(1)的解法
- 在O(n)时间复杂度O(1)空间复杂度求一个数组中出现多次和未出现的数字
- 在O(n)时间复杂度O(1)空间复杂度求一个数组中出现多次和未出现的数字
- 在一个数组中找出只出现一次的一个数字、两个数字,而其余数字全部成对出现。
- 【每日一题】查找一个字符串中第一个只出现两次的字符。要求时间复杂度为O(N),空间复杂度为O(1)
- 某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题
- 查找字符个数--查找一个字符串中第一个只出现两次的字符。比如:“abcdefabcdefabc”中第一个只出现两次为‘d’,要求时间复杂度为O(N),空间复杂度为O(1)
- 【字符串】查找一个字符串中第一个只出现两次的字符。比如:“abcdefabcdefabc”中第一个只出现两次为‘d’,要求时间复杂度为O(N),空间复杂度为O(1)
- 查找一个字符串中第一个只出现两次的字符。比如:“abcdefabcdefabc”中第一个只出现两次为‘d’,要求时间复杂度为O(N),空间复杂度为O(1)
- 查找一个字符串中第一个只出现两次的字符。比如:“abcdefabcdefabc”中第一个只出现两次为‘d’,要求时间复杂度为O(N),空间复杂度为O(1)
- 查找一个字符串中第一个只出现两次的字符,要求时间复杂度为O(N)。-替换字符串中的空格为$$$。要求时间复杂度为O(N)
- 基数排序java实现
- Elastix如何监听其它分机(图文)
- CSDN无语+恶心的待审核
- spring下载方法
- 开放录像服务器SDK接口(AnyChat Record Server SDK)
- 一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
- UFOs
- OC没有实现方法警告
- poj-3253 Fence Repair(哈夫曼树)
- myeclipse 安装phpeclipse插件
- 无题
- ural1109(二分图模板)
- Android中View更新方法Invalidate()和postInvalidate()
- check style配置详解