转载请注明出处:http://blog.csdn.net/ns_code/article/details/27568975


这篇文章没有代码。介绍的是纯理论的思路。

异或是一种基于二进制的位运算,用符号XOR或者 ^ 表示。其运算法则是对运算符两側数的每个二进制位,同值取0,异值取1。

它与布尔运算的差别在于,当运算符两側均为1时,布尔运算的结果为1,异或运算的结果为0。

异或的性质:

1、交换律:a^b = b^a;

2、结合律:(a^b)^c = a^(b^c);

3、对于随意的a:a^a=0,a^0=a。a^(-1)=~a。

了解了上面这些。来看看这个,非常重要。后面的程序都要用到这个结论:

对于随意的a,有a^b^c^d^a^k = b^c^d^k^(a^a) = b^c^d^k^0 = b^c^d^k,也就是说。假设有多个数异或,当中有反复的数,则不管这些反复的数是否相邻。都能够依据异或的性质将其这些反复的数消去。详细来说,假设反复出现了偶数次。则异或后会所有消去。假设反复出现了奇数次,则异或后会保留一个。

以下来看两道题目:

1、1-1000放在含有1001个元素的数组中,仅仅有唯一的一个元素值反复,其它均仅仅出现一次。每个数组元素仅仅能訪问一次,设计一个算法,将它找出来;不用辅助存储空间,是否能设计一个算法实现?

当然。这道题,能够用最直观的方法来做。将所有的数加起来,减去1+2+3+...+1000的和,得到的即是反复的那个数,该方法非常easy理解,并且效率非常高。也不须要辅助空间。唯一的不足时,假设范围不是1000。而是更大的数字,可能会发生溢出。

我们考虑用异或操作来解决该问题。

如今问题是要求反复的那个数字,我们姑且假设该数字式n吧,假设我们能想办法把1-1000中除n以外的数字所有异或两次。而数字n仅仅异或一次。就能够把1-1000中出n以外的所有数字消去,这样就仅仅剩下n了。

我们首先把所有的数字异或,记为T,能够得到例如以下:

T = 1^2^3^4...^n...^n...^1000 = 1^2^3...^1000(结果中不含n)

而后我们再让T与1-1000之间的所有数字(仅包括一个n)异或。便可得到该反复数字n。例如以下所看到的:

T^(a^2^3^4...^n...^1000) = T^(T^n) = 0^n = n

这道题到此为止。

2、一个数组中仅仅有一个数字出现了一次,其它的所有出现了两次,求出这个数字。

明确了上面题目的推导过程,这个就非常easy了,将数组中所有的元素所有异或,最后出现两次的元素会所有被消去,而最后会得到该仅仅出现一次的数字。

该题目相同能够该为例如以下情景,思路是一样的:数组中仅仅有一个数字出现了奇数次,其它的都出现了偶数次。

【剑指offer】异或去重的更多相关文章

  1. 剑指 Offer 56 - I. 数组中数字出现的次数 + 分组异或

    剑指 Offer 56 - I. 数组中数字出现的次数 Offer_56_1 题目描述 解题思路 java代码 /** * 方法一:数位方法 */ class Offer_56_1_2 { publi ...

  2. 【剑指offer】数组中仅仅出现一次的数字(1)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描写叙述: 一个整型数组里除了两个数字之外.其它的数字都出现了两次. 请 ...

  3. 剑指offer题解(Java版)

    剑指offer题解(Java版) 从尾到头打印链表 题目描述 输入一个链表,按从尾到头的顺序返回一个ArrayList. 方法1:用一个栈保存从头到尾访问链表的每个结点的值,然后按出栈顺序将各个值存入 ...

  4. 剑指offer二刷(精刷)

    剑指 Offer 03. 数组中重复的数字 题目描述 在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次. ...

  5. 面试题目——《剑指Offer》

    1.把一个字符串转换成整数——<剑指Offer>P29 2.求链表中的倒数第k个结点——<剑指Offer>P30 3.实现Singleton模式——<剑指Offer> ...

  6. [读]剑指offer

    研二的开始找工作了,首先祝愿他们都能够找到自己满意的工作.看着他们的身影,自问明年自己这个时候是否可以从容面对呢?心虚不已,赶紧从老严那儿讨来一本<剑指offer>.在此顺便将自己做题所想 ...

  7. 《剑指offer》全部题目-含Java实现

    1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. publi ...

  8. JS版剑指offer

    介绍 用JavaScript刷完了剑指offer,故总结下每道题的难度.解决关键点,详细题解代码可以点链接进去细看. 关于JS刷题的技巧可以看我之前的这篇:JS刷题总结. 剑指offer的题目在牛客网 ...

  9. 剑指offer题目java实现

    Problem2:实现Singleton模式 题目描述:设计一个类,我们只能生成该类的一个实例 package Problem2; public class SingletonClass { /* * ...

  10. 剑指offer(27)字符串的排列

    题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述:输入 ...

随机推荐

  1. MySQL 之Navicat Premium 12安装使用、pymysql模块使用、sql注入问题的产生与解决

    本文内容提要: Navicat Premium 12 的介绍.使用. pymysql模块的使用 sql注入问题的产生与解决 -------------------------------------- ...

  2. C# 反射总结

    反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...

  3. 【LeetCode】Count and Say(报数)

    这道题是LeetCode里的第38道题. 题目要求: 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数.其前五项如下: 1. 1 2. 11 3. 21 4. 1211 5. 111 ...

  4. main()中的参数argc, argv

    转自:http://blog.csdn.net/eastmount/article/details/20413773 一.main()函数参数 通常我们在写主函数时都是void main()或int ...

  5. ubuntu14.04LTS root登录出现错误

    输入root帐号和密码,出现以下错误: Error found when loading /root/.profile stdin:is not a tty 解决方法: 在终端中用命令:gedit / ...

  6. 一堆Offer怎么选?这样做就不纠结了

    有个朋友,工作了10年左右,春节后换工作,拿了三个Offer(西安): 通信行业的一家研究所,软件开发工程师,月薪7K,承诺有月奖金.年终奖金 一家做大数据的公司,软件开发工程师,月薪15K,13薪 ...

  7. Ubuntu16.04 on ThinkPad E455 不能识别耳机 的解决方法

    去年 (2016) 2月份在ThinkPad E455 上安装了Ubuntu 14.04 LTS (dual boot with Windows 10, upgraded to Ubuntu 16.0 ...

  8. You need to install the perl-doc package to use this program

    You need to install the perl-doc package to use this program 解决方案:apt-get install perl-doc

  9. Java中的自动类型转换

    Java里所有的数值型变量可以进行类型转换,这个大家都知道,应该不需要详细解释为什么. 2 在说明自动类型转换之前必须理解这样一个原则“表数范围小的可以向表数范围大的进行自动类型转换” 3 关于jav ...

  10. scrapy介绍及源码分析

    一 简介 Scrapy基于事件驱动网络框架 Twisted 编写.因此,Scrapy基于并发性考虑由非阻塞(即异步)的实现. 官方文档 :https://docs.scrapy.org/en/late ...