把一个连续数序列打乱判断少了那些数
2012-05-21 15:31
260 查看
/article/4462788.html
. 问题:100个连续的数打乱之后,随机取出1个数,问如何最快速的判断出少了哪一个?
分析:对于所有100个连续的数,只要除余100。一定在0~99之间。一般来说,比较常规的做法就是先排序(利用Hash表定位),在循环查找。当然时间复杂度是O(2n)。现在介绍一种很牛的O(n)做法:求二进制异或运算。
异或运算: 0^0=1^1=0; 0^1=1^0=1。0~99个数全部异或的结果只能是0。如果缺少一个数,那么全部异或的结果正好就是那个数。为什么呢?我们做个小实验:假如有四个数: 0001 0010,0101, 0110 排列成一个matrix.
bits: 1 2 3 4
0 0 0 1
0 0 1 0
0 1 0 1
0 1 1 0
全部异或: 0 0 0 0
我们可以下结论了,要全部异或的结果为0,那么所有bit位上的1的个数必须为偶数。反过来说:如果其中有一个数不存在了(比如0001),那么少0的的bit位上的值不变(因为1的个数还是偶数),而少1的bit位上的值就变成了1(1的个数为奇数了)。
在这里我又想到了以前遇到的几个使用异或来进行运算的例子:
第一个:使用异或交换两个数字的值
第二个:使用异或来选择两个数中的较大或较小者
第三个:一个序列中有奇数个数字,只有一个单独出现其他都是成对出现,快速找出这个单独出现的数字
这样0~99的道理也就一样了,所以异或的结果就是少的那个值。代码如下:
int data=0; for (int i=0;i<=99;i++) { if(70==i) continue; data=data^i; } cout << data << endl;
2. 问题:100个连续的数打乱之后,随机取出2个数,问如何最快速的判断出少了哪两个? (注意少2个数了)
分析:常用的做法可以先创建一个100个结构的Hash表,然后循环一次将所有数哈希100之后的位置上置1。然后顺序循环100次查找这个Hash表。前后需要O(2n)的时间。然而有没有更快速的做法呢?当然,直接操作bit.
假设我们有32个连续打乱的数字(0~31)缺少两个数2和11,希望把标记1标记在一个32位上。也就是一个整形变量,标记完之后就成为了:
bits position 31 30 29 28 ....... 11 10 .... 2 1 0
int a= 1 1 1 1 ....... 0 1 .... 0 1 1 (缺少数的bit位上为0)
至于如何标记成为a,我们可以看看下面的小段代码:
#include <iostream> #include <stack> using namespace std; typedef stack<int> sInt; sInt toBinary(unsigned int n){ sInt s; int i=n/2;//记录商值 int j=n%2;//记录余数 while(1) { s.push(j); if(0==i) break; j=i%2; i=i/2; } return s; } int main(){ unsigned int bits=0; for (int i=0;i<32;i++) { unsigned int bitMove=1; if(i==2||i==11) continue; bitMove=bitMove<<i; bits=bits|bitMove; } sInt sTmp; sTmp=toBinary(bits); while (!sTmp.empty()) { cout << sTmp.top(); sTmp.pop(); } return 0; }
相关文章推荐
- 判断一个数是否能分解为某个连续正整数序列之和
- 判断一个序列是否为栈的输出序列
- 判断一个数组序列为二叉树的后序遍历序列
- 判断一个序列是否时二叉排序树的后续遍历序列
- Java生物信息- 判断碱基有没有连续的重复序列
- 把一个包含n个正整数的序列划分成m个连续的子序列。设第i个序列的各数之和为S(i),求所有S(i)的最大值的最小值是多少?
- 连续数打乱判断出少了哪些数?
- 判断一个数据序列是否构成一个小根堆
- 定义一个整数N,不用本地变量和循环,输入N,依次判断2N,4N,8N...,一旦大于5000,则倒序输出小于5000的那些数(...,8N,4N,2N,N)
- 剑指offer:二叉搜索树的后序遍历序列(判断一个数组是否是二叉搜索树的后续遍历序列)
- (hdu step 8.1.2)Train Problem I(站的基本应用——判断一个序列经过栈后是否能够得到第二个序列)
- 判断一个序列是否是栈的合法序列
- 怎么判断一个序列是不是堆?
- [poj 1659 ]Frogs\' Neighborhood(Havel-Hakimi定理(判断一个序列是否可图))
- java 判断一个数组中的数值是否连续相邻
- 设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
- 判断一个序列是否是栈的弹出序列
- Havel-Hakimi定理(判断一个序列是否可图)
- 微软算法100道题-------输入两个整数序列。其中一个序列表示栈的push顺序, 判断另一个序列有没有可能是对应的pop顺序。
- 输入一个正数 n,输出所有和为 n 的连续正数序列 [No. 25]