我在解决Hackerrank的挑战时遇到了这个问题。
/*
Problem Statement
There are N integers in an array A. All but one integer occur in pairs. Your task is to find the number that occurs only once.
Input Format
The first line of the input contains an integer N, indicating the number of integers. The next line contains N space-separated integers that form the array A.
Constraints
1≤N<100
N % 2=1 (N is an odd number)
0≤A[i]≤100,∀i∈[1,N]
Output Format
Output S, the number that occurs only once.
*/
我在这种情况下写的正常解决方案结果非常复杂,有很多嵌套的if循环。在搜索了一下,我发现这个解决方案通过简单地将整数数组中的所有元素相互异或来解决问题,结果就是孤立的整数。
这是相关的方法(main()方法,它接受输入并将其解析为未显示的整数数组,因为它在这里不相关):
static int lonelyinteger(int[] a) {
int n = a.length;
int result = 0;
for( int i = 0; i < n; i++) {
result = result ^ a[i];
}
return result;
}
我不确定这个XOR操作如何能够返回数组中的“孤独整数”。我知道XOR的两个属性,如:
1. a^a=0
2. a^0=a
但除此之外,我无法弄清楚XOR如何在这里工作。
SO上有another question内容相同,但提出了另一个问题,所以我不得不再问这个问题。
如果有人能为此XOR操作提供详细解释,我将非常感激。
答案 0 :(得分:2)
由于a^a
对于任何a
等于0,所有匹配的整数对将相互抵消,留下0.然后用最终数字进行异或。由于任何0^a
a
等于a
,因此结果将是最终数字。
简单的演示:
$ ruby -e 'puts [1,1,2,2,3,3,4,5,5,6,6].reduce :^'
4
如果您浏览单个对,您可以看到为什么会这样:
1 ^ 1 = 0
0 ^ 2 = 2
2 ^ 2 = 0
0 ^ 3 = 3
3 ^ 3 = 0
0 ^ 4 = 4
4 ^ 5 = 1
1 ^ 5 = 4
4 ^ 6 = 2
2 ^ 6 = 4
结果在0和最新数字之间切换,直到你到达孤独者;之后它会切换到那个号码和......当你用最新的号码对它进行异或时你得到的东西。那里的实际值并不重要,因为当你在该号码的第二个副本中进行XOR时它会被删除,并且你会回到单身人士的副本。
我对这些数字进行了排序,以便很容易找到单身人士,但是由于XOR撤消了自身,所以顺序并不重要:
$ ruby -e 'puts [6,3,4,1,1,2,2,6,3,5,5].reduce :^'
4
6 ^ 3是...某个数字,然后那个数字^ 4是另一个数字,然后你用1对其进行异或,并且没有一个重要,因为那时你撤消1,然后你扔另一个使用2的中间结果并立即撤消它,然后你撤消6和3,所以你回到4.你与5进行XOR以获得另一个短暂的数字然后被冲走决赛5,再次离开,4。