面试题1:落单的数
来源:互联网 发布:如何预防网络成瘾 编辑:程序博客网 时间:2024/04/28 02:27
题目来源:微信公众平台九章算法。由于九章算法只给出了算法,并没有给出源代码,这里笔者根据自己的能力给出了源代码,当然可能会有很多不足,希望大家不吝指教。 -——— 肖然
题目描述:
有2n+1个数,其中2n个数两两成对,1个数落单,找出这个数。要求O(n)的时间复杂度,O(1)的空间复杂度。进阶问题:如果有2n+2个数,其中有2个数落单,该怎么办?
题目分析:
异或的性质,对于任意a,a^a=0; a^0=a;根据这两条性质可以写出下列代码。
初阶:将2n+1个数异或起来,相同的数会抵消,异或的答案就是要找的数。
进阶:假设两个不同的数是a和b,并且a!=b,将2n+2个数异或起来就会得到c=a xor b,并且c不等于0。因此在c的二进制位中找到一个为1的位,可推断在这位上a和b分别为0和1,因此将2n+2个数分为该位位0的组和该位为1的组,两组中各自会包含2n’+1个数和2n’’+1个数,用初阶的算法即可解决。
源代码:
/**
*九章算法面试题一、落单的数
*异或的简单应用
*异或的性质: a^a=0; a^0=a;
*/
#include<iostream>
#include<cstdio>
using namespace std;
int a[10000],b[10000];
int ans,ans0,ans1;
int LuoDan1(int n,int *a){//初阶问题,给出2*n+1个数,只有一个是单个的,求这个数
ans=0;
for(int i=0;i<2*n+1;i++){
ans^=a[i];
}
return ans;
}
int Judge(int n,int k){//判断第k位(从右到左)是否为1
int i=1;
while(i++<k-1) n>>=1;//向左移位k-1位
if(n>>1==1) return 1;//第k位是1,返回1
else return 0;
}
int LuoDan2(int n,int *a){//初阶问题,给出2*n+2个数,只有两个是单个的,求这两个数
ans=0;
for(int i=0;i<2*n+2;i++){
ans^=a[i];
}
int k=1;
//cout<<ans<<endl;
while(ans>0){//找到最低位的1
if((ans&1)==1) break;
++k;
ans>>=1;
}
ans0=ans1=0;
for(int i=0;i<2*n+2;i++){
if(Judge(a[i],k)){//第k位为1
ans1^=a[i];
}
else ans0^=a[i];
}
//cout<<ans0<<" "<<ans1<<endl;
return ans;
}
int main()
{
int n;
while(cin>>n){
int ans=0;
for(int i=0;i<2*n+1;i++){
cin>>a[i];
//ans^=a[i];
}
cout<<LuoDan1(n,a)<<endl;
for(int i=0;i<2*n+2;i++){
cin>>b[i];
}
//cout<<ans<<endl;
LuoDan2(n,b);
cout<<ans0<<" "<<ans1<<endl;
}
return 0;
}
- 面试题1:落单的数
- 面试题1 落单的数
- 面试题1 落单的数
- 九章算法面试题1 落单的数
- Java实现-落单的数1
- 落单的数
- LinCode落单的数
- 落单的数
- 题目:落单的数
- 落单的数 III
- 落单的数 II
- 落单的数
- 落单的数
- LinCode落单的数
- LintCode_82_落单的数
- lintcode ----落单的数
- LintCode 落单的数
- 落单的数
- Visual Basic 跳蚤算法模块
- coco2d学习之CCNodeColor
- #error WINDOWS.H already included. MFC apps must not #include <windows.h>
- matlab中uigetfile的用法
- 【转载】JSP九大内置对象
- 面试题1:落单的数
- 开源中国客户端笔记记录
- 自动获取String的长和高(可作用于label)
- django模版local variable 'has' referenced before assignment
- C语言第七课
- Sicily 1014 畅通工程
- 数据结构学习笔记(二)------------线性表之链式存储
- python2.7中文乱码解决方案
- wifi共享精灵 设置热点后 电脑上不了网