我有一个正整数的数组。除了此数组中的一个元素之外的所有元素都没有重复。找到唯一元素的方法是使用XOR按位运算符,仅当元素之一为1时返回1,否则返回false。
以下是代码:
public class Bitter {
public static void main(String[] args) {
int[] deliveryIds = {34, 40, 2, 21, 50, 40, 34, 2, 50};
System.out.println(new Bitter().findUniqueDeliveryId(deliveryIds));
}
public int findUniqueDeliveryId(int[] deliveryIds) {
int uniqueDeliveryId = 0;
for(int i = 0; i < deliveryIds.length; i++) {
uniqueDeliveryId ^= deliveryIds[i];
}
return uniqueDeliveryId;
}
}
在循环中,数组中的每个整数都与从1开始的uniqueId进行异或。然后,0与34进行异或。结果然后与数组40中的下一个整数进行异或运算通过整个阵列。
即使在设置断点并一次遍历整个流程之后,我仍然无法理解,如何使用uniqueId(从它的值0开始)进行异或可以帮助我们找到数组中的非重复整数?
不应该像自己的40个XOR一样(导致值为0),以确认它是重复的。与此不同的是,我们与数组中的第一个整数进行异或运算,结果与数组中的后续数字相对应。我缺少什么/
答案 0 :(得分:5)
XOR
n个数字就像计算每个位置的1位数,如果计数是奇数,则将相应的输出位设置为1。您XOR
的顺序并不重要。
如果一个数组包含x对相等数字和一个唯一数字,则相等对的位相互抵消(因为它们在每个位置贡献偶数个1),只留下唯一数字的位
例如,请使用以下数字列表:
100100101
010110110
101101100 // the unique number
100100101
010110110
计算每个位置的1的数量:
321521522
XOR的结果(每个奇数计数为1位):
101101100
这是列表中的唯一唯一编号。
答案 1 :(得分:5)
把它看作数学,而不是代码;使用^
表示bit-level xor
,我们可以说
A ^ B = B ^ A
(A ^ B) ^ C = A ^ (B ^ C)
A ^ 0 = A
A ^ A = 0
前两个属性意味着对x序列的任何重新排序都会产生完全相同的结果。
因此,给定一个包含重复项的序列,它们都将通过xor:
删除 A ^ B ^ X ^ A ^ B = A^A ^ B^B ^ X = 0 ^ 0 ^ X = X
\ reorder \ xoring twice \ removing zeroes
请注意,只有当一个元素不重复时,此技巧才有效。如果有多个,结果将是所有非均匀重复元素的异或:
A ^ B ^ C ^ A = A^A ^ B ^ C = B ^ C