您将获得一个包含正整数的数组。除了一个整数之外,所有整数都会出现偶数次。找到这个特殊的整数。
解决方案:
具有奇数出现次数的整数将具有0对或更多对以及一个单个数字。所以,如果我们能够如何摆脱所有对,那么我们剩下的就是单个数字。什么摆脱对?提示:想想一个运营商。
XOR会做到这一点。它为您提供O(n)解决方案,没有额外的内存。
int GetSpecialOne(int[] array, int length)
{
int specialOne = array[0];
for(int i=1; i < length; i++)
{
specialOne ^= array[i];
}
return specialOne;
}
答案 0 :(得分:8)
因为(N xor Q)xor Q = N而起作用。
恰好一个整数存在奇数次,因此它将是唯一不从列表中“消失”的数字。所有其他数字都存在偶数次,因此它们都以2的组(可以想象)出现,因此它们都“消失”。此外,XOR之间的“距离”无关紧要:(((N x或Z)x或Q)xor Z)xor Q = N.即使在对之间存在中间XOR,Z'和Q'也会“抵消”
答案 1 :(得分:3)
XOR运算符具有(a ^ a) == 0
和({扩展名] (a ^ b ^ a) == b
的属性。因此,任何偶数次出现的值都会在XOR“累积”中“取消”为零,只留下奇数。
答案 2 :(得分:1)
事实一:x XOR x
为零。
这是因为0 XOR 0
为零且1 XOR 1
为零。
事实二:x XOR x XOR x ... x
为零,x
出现偶数次。
这是事实上的归纳法。
事实三:x XOR x XOR x ... x
为x
,其中x
出现奇数(如果有的话)。
通过将表达式写为
,从事实二开始(x XOR x XOR x ... x) XOR x = 0 XOR x = x
如果原件中有2n
个术语,则括号中有2n + 1
个术语。
事实四:XOR
具有联想性和可交换性。
这很容易验证。
现在很清楚这段代码是如何工作的。通过此代码将出现偶数次数的数字减少到零。这个代码减少了出现奇数次的唯一数字。
答案 3 :(得分:0)
^
是exclusive or operator
。按位异或运算符的两个操作数必须是整数类型。按位异或运算符将其第一个操作数的每个位与其第二个操作数的相应位进行比较。如果一位为0而另一位为1,则相应的结果位设置为1.否则,相应的结果位设置为0.
如果两者都为高或低,则输出为0,在所有其他情况下,输出为1.
Ex: a ^ b ^ a ^ a ^ b ^ c ^ c =&gt; (c ^ c = 0; b ^ b = 0; a ^ a = 0;最后留下0 ^ 0 ^ 0 ^ a = a)。因此,在序列中偶数次重复之间重复奇数次的数是输出。您可以使用相同的示例,获取数组元素。