给定是一个整数数组。阵列中的每个数字都出现ODD次数,但只有1个数字出现偶数次。找到那个号码。
下面是我在stackoverflow上读到的解决方案,它不起作用。我无法找到该解决方案的链接,我想知道是否有人可以帮助我理解为什么这个解决方案不正确,除非我在下面做错了。
我们首先对阵列中的所有元素进行异或。让我们称之为aWithOutDuplicate
,其中包含除重复元素之外的所有奇数元素。然后我们或所有的元素。让我们称它为aAllUnique
,它应该包含所有独特的元素。 XORing aWithOutDuplicate
和aAllUnique
应该吐出重复的元素。
int arr[] = {1,2,3,4,5,6,7,8,4,9};
int aWithOutDuplicate = 0;
int aAllUnique = 0;
for(int i=0;i<arr.length;i++) {
aWithOutDuplicate ^= arr[i];
aAllUnique |= arr[i];
}
cout << (aWithOutDuplicate ^ aAllUnique);
更新: 我想知道这个问题是否可以在O(n)时间和O(1)空间复杂度中得到解决。
答案 0 :(得分:3)
如果数组元素在[1,n-1]范围内,对于大小为'n'的数组,此O(n),O(1)空间解决方案 ONLY 。 [适用于[0,n-1]并进行下面的一些调整]
扫描阵列并执行以下操作
for(i=0; i < n; i++)
A[A[i]]=A[A[i]]*(-1)
所有出现奇数的数组元素在扫描结束时都会显示负值。具有偶数次数的元素将具有正值。
一些调整: 如果数组范围是[0,n-1],则可以为“0”设置一个特殊情况,在第一次传递期间用特殊字符替换“0”(而不是否定)。您必须在第二遍期间将特殊字符恢复为“0”,依此类推。
答案 1 :(得分:0)
这种方法不起作用,因为没有办法区分出现偶数次的数字与从未出现的数字。考虑这个4位示例:
5: 1 0 1
10: 0 1 0 1
-----------
1 1 1 1 <- both or and xor.
现在,将两个数字(&lt; = 15,因为它是4位)添加到列表中。或者将保持不变,因为所有位都已打开,0xf | x == 0xf
表示x的所有4位值。 xor将保持不变,因为0xf ^ x ^ x == 0xf
表示x的所有值。因此,您的方法的一个反例可能是,例如, {5, 10, 1, 1}
。
答案 2 :(得分:0)
假设您有阵列:a,b,a,b,a,c 所以输出应该是b。 我将尝试解释为什么你的算法是wronng。当您应用OR操作时,您假设您将获得唯一的数字。是的,当然是| a | a == a,但通过执行以下操作可获得什么价值:a | b | c ==? (可能所有位都将设置为1,具体取决于a,b,c) 它与做XOR不同。
答案 3 :(得分:0)
在下面的代码中,我发现了重复偶数个时间的数字,遵循蛮力方法而不使用标准库函数映射:
//! Print integers occurring an even number of times in array a.
#include <iostream>
int main() {
int arr[] = { 9, 12, 23, 10, 12, 12, 15, 23, 14, 12, 15 };
int n = sizeof(arr) / sizeof(arr[0]);
int b[n], count = 0, c[100];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
if (arr[j] == arr[i])
b[i] = ++count;
count = 0;
}
for (int i = 0; i < n; i++)
c[arr[i]] = 0;
for (int i = 0; i < n; i++) {
if (c[arr[i]] == 1)
continue;
if (b[i] % 2 == 0)
std::cout << arr[i] << std::endl;
c[arr[i]]++;
}
return 0;
}