可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Given is an array of integers. Each number in the array occurs an ODD number of times, but only 1 number is occurring an EVEN number of times. Find that number.
Below is the solution I read on stackoverflow that does NOT work. I am unable to find the link to that solution and I was wondering if somebody could help me understand why this solution is incorrect unless I am doing something wrong below.
We first XOR all the elements in the array. Lets call it aWithOutDuplicate
which contains all the odd elements except for duplicate one. We then OR all the elements. Lets call it aAllUnique
that should contain all the unique elements. XORing aWithOutDuplicate
and aAllUnique
should spit out the duplicate element.
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);
Update: I wonder if this problem can be solved in O(n) time and O(1) space complexity.
回答1:
That approach does not work because there is no way to differentiate a number that appears an even number of times from one that never appears at all. Consider this 4-bit example:
5: 1 0 1 10: 0 1 0 1 ----------- 1 1 1 1 <- both or and xor.
Now, add ANY number (<= 15 since it's 4 bits) to the list twice. The or will stay the same because all the bits have been switched on and 0xf | x == 0xf
for all 4-bit values of x. The xor will stay the same because 0xf ^ x ^ x == 0xf
for all values of x. So a counterexample to your method could be, e.g. {5, 10, 1, 1}
.
回答2:
This O(n), O(1) space solution works ONLY if the array elements are in the range [1,n-1] for an array of size 'n'. [Will work for [0,n-1] with a few tweaks mentioned below]
Scan the array and do the following
for(i=0; i < n; i++) A[A[i]]=A[A[i]]*(-1)
All array elements with odd occurrences will have a negative value at the end of the scan. The element with the even number of occurrence will have a positive value.
A few tweaks: If the array range is from [0,n-1], you can have a special case for '0' where you replace '0' with a special character during the first pass (instead of negation). You will have to revert back the special character back to '0' during the 2nd pass and so on.
回答3:
Suppose you have the array: a, b, a, b, a, c So the output should be b. I'll try to explain why your algorithm is wronng. When you apply OR operation, you assume you will get the unique numbers. Yes, of course, a | a | a == a, but what value will you get by doing the following: a | b | c == ? (Probably all bits will be set to 1s, depending on a,b,c) It's not the same as doing XOR.
回答4:
In below code I've found the numbers which are repeating even number of time, following brute force approach without using standard library function map:
//! 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; }