We do not need to list (2 ** n) subarrays to solve this problem.
XOR has some useful properties that we can use to solve this problem in O (n) time. In particular:
To solve your problem, you first need to calculate how many times each element appears in subarrays. Any item that appears an even number of times can be ignored. The rest must be XORed together (each taken only once).
See how this applies to your example:
1 XOR 2 XOR 3 XOR (1 XOR 2) XOR (2 XOR 3) XOR (1 XOR 2 XOR 3) =
The following is the O (n) implementation of this idea:
def xor_em(lst): n = len(lst) ret = 0 for i, el in enumerate(lst): count = (i + 1) * (n - i) if count % 2: ret ^= el return ret print xor_em([1, 2, 3])
Subarray counting is done
count = (i + 1) * (n - i)
using the observation that there are elements i + 1
left of the current element (including yourself) and n - i
to the right (also including yourself). Multiplying two gives the number of subarrays that start to the left of the current element and end to the right of it.
Now we have reduced the problem of finding pairs (i + 1)
and (n - i)
whose product is odd. Note that the only way to get an odd product is to multiply two numbers, which themselves are odd (this can be seen by thinking about simple factorizations of two animations).
Two cases can be considered:
- when
n
even, one of (i + 1)
and (n - i)
always even. This means that the algorithm always returns zero for lists of even length. - when
n
is odd, (i + 1) * (n - i)
is odd for i = 0, 2, 4, ..., (n - 1)
.
This leads to the following simplified solution:
def xor_em(lst): if len(lst) % 2 == 0: return 0 else: return reduce(operator.xor, lst[::2])
source share