里面提到了异或运算:
异或运算是什么,我真是不怎么知道。
在这里补一下。
异或,英文为exclusive OR,缩写成xor
它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为:
a⊕b = (¬a ∧ b) ∨ (a ∧¬b)
如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0
让我们先来考虑一个比较简单的问题:
如果除了一个数字以外,其他数字都出现了两次,那么如何找到出现一次的数字?
答案很简单:全员进行异或操作即可。考虑异或操作的性质:对于两个操作数的每一位,相同结果为 00,不同结果为 11。那么在计算过程中,成对出现的数字的所有位会两两抵消为 00,最终得到的结果就是那个出现了一次的数字。a^a=0 a^0=a
接下来是&运算
运算规则:
0&0=0;0&1=0;1&0=0;1&1=1
即:两个同时为1,结果为1,否则为0
例如:3&5
十进制3转为二进制的3:0000 0011
十进制5转为二进制的5:0000 0101
那么这个思路也就是接下来找到,两个单独数字的思路了~
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6] 输出:[1,6] 或 [6,1]示例 2:
输入:nums = [1,2,10,4,1,4,3,3] 输出:[2,10] 或 [10,2]
限制:
2 <= nums.length <= 100004 ^ 1 ^ 4 ^ 6 => 1 ^ 6
6 对应的二进制: 110 1 对应的二进制: 001 1 ^ 6 二进制: 111 此时我们无法通过 111(二进制),去获得 110 和 001。
那么我们如果能够把这两个数分开组就好了~。
那么怎么分组呢?
因为两个数,二进制的话,至少有一位不一样,
根据上图,进行异或运算。
最终的得到的数字 1 ^ 6 二进制: 111 (不一样有值,那么下面用最低位 001其实他们两个就是不一样的)
相当于一个mask(用于分组)。
那么根据这个mask的最低位,我们就可以做与运算的时候
比如说这两个数字,就是最低位是1,那么说明这两个数字
比如所有的数字跟001进行与运算的时候,如果最低位为1,那么就与运算就有值,否则没有,那么肯定能把这两个数字弄到不同的分组。
那么初始化一个a和b做两个数字的计数。
if ((num & mask) == 0) { a ^= num; } else { b ^= num; }与运算与这个mask的时候,等不等于0就可以区分这两个数字了。
感谢题解:
https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/jie-di-qi-jiang-jie-fen-zu-wei-yun-suan-by-eddievi/