【剑指offer】异或去重
来源:互联网 发布:5到25个字的淘宝会员名 编辑:程序博客网 时间:2024/05/22 15:48
这篇文章没有代码,介绍的是纯理论的思路。
异或是一种基于二进制的位运算,用符号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的和,得到的即是重复的那个数,该方法很容易理解,而且效率很高,也不需要辅助空间,唯一的不足时,如果范围不是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、一个数组中只有一个数字出现了一次,其他的全部出现了两次,求出这个数字。
明白了上面题目的推导过程,这个就很容易了,将数组中所有的元素全部异或,最后出现两次的元素会全部被消去,而最后会得到该只出现一次的数字。
该题目同样可以该为如下情景,思路是一样的:数组中只有一个数字出现了奇数次,其他的都出现了偶数次。
异或是一种基于二进制的位运算,用符号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的和,得到的即是重复的那个数,该方法很容易理解,而且效率很高,也不需要辅助空间,唯一的不足时,如果范围不是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、一个数组中只有一个数字出现了一次,其他的全部出现了两次,求出这个数字。
明白了上面题目的推导过程,这个就很容易了,将数组中所有的元素全部异或,最后出现两次的元素会全部被消去,而最后会得到该只出现一次的数字。
该题目同样可以该为如下情景,思路是一样的:数组中只有一个数字出现了奇数次,其他的都出现了偶数次。
0 0
- 【剑指offer】异或去重
- 【剑指offer】异或去重
- 【剑指offer】异或去重
- 【剑指offer】异或去重
- 【剑指offer】异或去重
- 【剑指offer】异或去重
- 【剑指offer】异或去重
- 【剑指offer】异或去重
- 异或去重
- 面试题:异或去重
- 剑指Offer----面试题28:字符串的排列 & 去重
- 我理解的剑指offer-----之“数组中只出现一次的数字系列”的基础----异或去重
- 剑指offer - 面试题28:字符串的排列(递归+去重)
- 剑指offer 字符串的排列原题,java实现,组合排列去重
- 大数据排序或取重或去重相关问题
- 大数据排序或取重或去重相关问题
- 【大数据】大数据排序或取重或去重相关问题
- 大数据排序或取重或去重相关问题
- redhat6.5 替换成centos6.5 yum
- 基于色彩恒常( color constancy)特性的Frankle-McCann Retinex图像增强
- 落幕,并不完美地结局!
- js效果实现页面的局部打印
- 在Windows上以服务方式运行 MSOPenTech/Redis
- 【剑指offer】异或去重
- 深入理解C++中的常量引用
- codeforces#248_div2_A Kitahara Haruki's Gift dp
- 获取服务器信息
- 关于thinkphp关联模型的HAS_ONE
- NanShan CFileFind 查找文件/文件夹 最简单的实现源码
- 一个人的浪漫的季节
- Eclipse选项卡式的属性视图(The Eclipse Tabbed Properties View)
- android从网络上异步加载图像