This is a slightly trickier version of The Missing Duplicate Number. Instead of one single missing number, we have 2.
Problem : Given an array of Integers. Each number is repeated even number of times. Except 2 numbers which occur odd number of times. Find the two numbers Ex. [1,2,3,1,2,3,4,5] The Output should be 4,5.
The naive solution is similar to the previous solution. Use a hash table to keep track of the frequencies and find the elements that occur an odd number of times. The algorithm has a Time and Space Complexity of O(n).
Say those two required numbers are a and b
If you remember the previous post, we used the XOR over all the elements to find the required element. If we do the same here, we get a value xor which is actually a ^ b.
So how can we use this? We know that a and b are different, so their xor is not zero. Infact their XOR value has its bit set for all its dissimilar bits in both a and b. (eg. 1101 ^ 0110 = 0011).
It's important to notice here that each bit set in xor corresponds to either a or b, but not both. So we isolate a single bit from xor , say mask, and run the original XOR algorithm only for those number whose bit is set the same as mask. This list of elements will either have a or b. depending on whether the bit was set due to a or b. So the xor algorithm will return one of the numbers,say xor_1. To obtain the other we simply xor ^ xor_1.
Example:
[1,2,3,4,5,1,2,3]
xor = 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 1 ^ 2 ^3 = 1 ( = 4 ^ 5)
Notice, 4 = 0100 and 5 = 0101 , xor = 0001.
In this case, since there's just one bit set, xor itself is the mask.
Now, we calculate xor_1. Ie XOR all number whose (v & mask) != 0
xor_1 = 1 ^ 3 ^ 5 ^ 1 ^ 3 = 5
xor_2 = xor ^ xor_1 = 1 ^ 5 = 4
We obtain (4,5) which occurred odd number of times.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
r = {random.randint(10,100) for i in xrange(10)} | |
lst = random.sample(r,len(r)) | |
l = lst[:2] + lst[2:] * 2 | |
random.shuffle(l) | |
def missing_2_numbers(lst): | |
xor = reduce(lambda a,b : a ^ b, lst) | |
mask = (xor & -xor) #get the right most set bit. | |
xor_1 = 0 | |
for v in lst: | |
if v & mask: | |
xor_1 = xor_1 ^ v | |
return (xor_1,xor ^ xor_1) | |
print l | |
print missing_2_numbers(l) |
Comments
Post a Comment