位运算:找出来数组中落单的两个数
题目大意
每次给你 2 * n + 2 个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字并升序输出。
思路
最简答的想法,排序,然后找出只出现一次的数,不再叙述。
来说一说用位运算怎么解决:
假设这两个不同的数 x2 = 1100101 和 y2 = 1010001。
观察标记出来的位置。易知,对于两个不同的数,一定有一个位置 pos 对应这两个数在二进制下是不同的。 上边的例子中,pos = 3
我们这里先讲两个前导知识:
0 ^ x = x,x 异或 0 的结果还是 x
x ^ x = 0,两个相同的数异或结果为 0
根据这两个性质,我们可以在 2 * n + 1 个数中,轻易的找出落单的一个数。eg: 1 ^ 1 ^ 2 ^ 2 ^ 3 = 3
我们结合刚刚的结论,如何用前导知识来找出落单的两个数。
我们就刚刚的 x 和 y 来讲,x 对应的二进制数下第 3 位是 1,而 y 对应的二进制数下第 3 位是 0。
要是我们把这 2 * n + 2 中,二进制数下第 3 位是 1 的所有数都拿过来,就会变成这样:
x = 110 0101
a1 = 110 1101
a2 = 110 1101
a3 = 101 1101
a4 = 101 1101
很明显,x ^ a1 ^ a2 ^ a3 ^ a4 = x。
同样的对于二进制数下第 3 位是 0 的所有数:
y = 101 0001
a5 = 110 1001
a6 = 110 1001
a7 = 101 1001
a8 = 101 1001
y ^ a5 ^ a6 ^ a7 ^ a8 = y。
也就是,我们对 2 * n + 2 个数,依据在 pos 下的数值分组即可。
现在的问题就是,如何找到 x 和 y 对应的 pos。
这里再来一个前导知识,x & (x-1) 的结果为:x 减去其二进制下从右往左数的第一个 1.
eg: x = 11010,那么 x & (x-1) = 11000
如果我们让 x 减去 x &(x-1), 这时的结果为:x 对应二进制下第一个 1 表示的数
eg: x = 11010,x - (x & (x-1)) = 00010
ps:位运算的优先级是最低的,记得加括号。x - (x & (x-1)) = x & (x^(x-1)),有兴趣自己证明吧
异或运算是相同位为 0, 不同位为 1。
令 z = x ^ y = 1100101 ^ 1010001 = 110100。
观察 z 我们可以发现,z 在二进制下从右往左的第一个 1 就是 x 和 y 对应的 pos。
到这里这个问题就结果了,具体看代码吧:
代码
#include<stdio.h>int a[10005]; int main(){int n, i;scanf("%d", &n);n = n * 2 + 2;for(i = 0; i < n; i++) scanf("%d", &a[i]);int z = 0;for(i = 0; i < n; i++) z ^= a[i]; // 对所有数异或,相同的数异或结果位 0,最终的z = x ^ yint pos = z - (z & (z-1));// 找到 z 在二进制下第一个 1,也就是 x 和 y 在二进制下第一个不同的位置 int x = 0;for(i = 0; i < n; i++){if((pos & a[i]) != 0){ // 找到所有的在 pos 这个位置为 1 的数 x ^= a[i];}} // 解释一下 if 判断, 100 & 101 = 100, 100 & 001 = 0, 达到一个分组的目的int y = z ^ x; // z = y ^ x, z ^ x = y ^ x ^ x = yif(x > y) printf("%d %d\n", y, x);else printf("%d %d\n", x, y);return 0;
}
位运算:找出来数组中落单的两个数相关推荐
- 小小c#算法题 - 1 - 找出数组中满足条件的两个数
把一些东西放到网上,看的时候方便一些.代码可能有bug且不是最佳解决方案,仅供参考. 题目:输入一个按升序排序的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字. 要求时间复杂度是 ...
- 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...
- python步骤解析 给定一个整数数组和目标值_给定一个整数数组和一个目标值,找出数组中和为目标值的两个数 例如给定nums = [2,7,11,15],target = 9...
python解决方案 nums = [1,2,3,4,5,6] #假如这是给定的数组 target = 9 #假如这是给定的目标值 num_list = [] #用来装结果的容器 def run(nu ...
- 找出数组中不重复的一个数
只出现一次的数字给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 ...
- 异或方式找到一组数组中不重复的两个数(同班同学方法)
源代码如下: #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { int ...
- 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)
1.8*8的棋盘上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下 ...
- c语言实现在数组中找一个数字显示,C语言找出数组中的特定元素的算法解析
问题描述:一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它.能否只用一个额外数组和少量其它空间实现. 思路:如果能用两个辅助数组,那么相对 ...
- java数组出现次数最多的数_找出数组中出现次数最多的那个数——主元素问题...
方法一:以空间换时间,可以定义一个计数数组int count[101],用来对数组中数字出现的次数进行计数(只能针对数组中数字的范围1~100),count数组中最大的元素对应的下标,即为出现次数最多 ...
- 图解面试题:找出数组中重复的数字?
今天分享的题目来源于 LeetCode 上的剑指 Offer 系列 面试题03. 数组中重复的数字. 题目链接:https://leetcode-cn.com/problems/shu-zu-zhon ...
最新文章
- python【Matlibplot绘图库】画多个曲线的折线图(Matplotlib.pyplot.plot)
- Javascript 进阶 作用域 作用域链
- tcl mysql_MySQL·TCL语言
- 括号配对问题(C++栈)
- RabbitMQ的5种队列_简单队列_入门试炼_第4篇
- mysql中数组转list,Arrays.asList(T... a) 不转换基本类型数组值为list
- Android开发笔记(五十三)远程接口调用AIDL
- win7系统的设置在哪里_win10系统改装win7之BIOS设置教程
- java 枚举 映射_java – 如何将值映射到枚举?
- Python鼠标拖动曲线(matplotlib)
- cv2.rectangle--TypeError: an integer is required (got type tuple)
- FILCO蓝牙CSR4.0驱动安装连接(解决蓝牙连接的终极管理方法,速度极快)
- JAVA将英文字母的大写字母转换为小写字母。
- 作图,用ECharts就够了
- bitbucket配置_Bitbucket和Confluence安装配置
- 基于Java的飞机雷电射击游戏的设计实现(Eclipse开发)
- alipay 证书 java_支付宝转账-提取根证书失败 AlipayRootCert Is Invalid
- ANSYS meshing 生成的网格转到Openfoam中报错
- mkv怎么转换成mp4,mkv转mp4超简单
- SCADE Display(Arinc661)图像的分解显示
热门文章
- 立下19年的flag,跪着也要完成!
- 中国科学技术大学计算机考研难吗,中国科学技术大学(专业学位)计算机技术考研难吗...
- google论文--mapred中文翻译
- Apple下载Xcode安装包
- 徐登科浅谈币圈:从口罩现在只需0.9元/只,看看机会变成陷阱最短需要多久呢?
- iOS开发点击查看图片详情并可缩放拖拽图片长按图片下载
- js获取一年前的时间,几个月前的今天
- 人机融合智能的新思考
- hackerrank - Basic Join - Challenges
- mysql 拼音排序_MySQL按常规排序、自定义排序和按中文拼音字母排序的方法