XOR of 2 lists elements wise in a simple approach - xor

I wish to do xor of all elements in 2 lists a=[1,2,3], b=[3,4,5] the result should be [2,5,4,1,6,7,0,7,6] in O(1) or O(N).
Please explain your solution as well as approach.

I'm Assuming you want to XOR all elements in A with all elements in B, in this case, O(N) algorithm will need to run in size of A * Size of B.
The solution could be like this
let L equal list
For each item in A
For each item2 in B
L.add(item Xor item2)
This is linear on the combined size of A and B

Related

How to find all the subarrays with xor 0?

The problem is to find all the subarrays of the given array with xor of all its elements equal to zero.
For example, if array contains elements [13,8,5,3,3], the solution should give the indices of all subarrays like 0-2, 3-4, 0-4, etc.
The question is similar to the one asked here
The only difference is that I want the indices of all the subarrays that satisfies the equation A0 xor A1 xor...xor An = 0
This is a fairly straightforward extension of the linked question. In Python,
# Multivalued map from the XOR of array[:i] to i for all i.
prefix_xor_to_stops = {0: [0]}
prefix_xor = 0
for j, x in range(array):
prefix_xor ^= x
# Returns the value associated with prefix_xor. Inserts [] if not present.
stops = prefix_xor_to_stops.setdefault(prefix_xor, [])
for i in stops:
yield (i, j+1)
stops.append(j+1)
As before, the idea is that a subarray array[i:j] has XOR zero if and only if the XOR of array[:i] equals the XOR of array[:j]. For each subsequent element of the array, we compute the XOR of the prefix ending at that element from the XOR of the prefix ending at the previous element, then look up all of the solutions i to the above equation. Then we insert the new association and continue.
If you want to modify the answer mentioned in the post then i hope you have understood that solution very well.
Now the thing which is missing in that solution is that its only storing the first index occurrence of a particular prefix xor sum. Other indexes where the same xorSum occurs are not tracked. So what you have to do is modify map to keep a list(vector in C++) of indexes for each xorSum.
If you have two different prefixes of the array with equal xor, let's say prefix of length x1 and prefix of length x2, then subarray from x1 + 1 to x2 has xor equal to 0. Make a dictionary (BST, hash table, whatever similar) and store there pairs (value of prefix sum, prefixes that gives that value). Any two elements with the same value give you one subarray. You can also find it using Trie if you like.
Using Trie:
At the beginning Trie consists of single node and no edges. We want to add to it numbers. It would also be convenient to index them, since we want to find all subarrays. Each node that represents some numbers (multiple in case of duplicates) in Trie will store list of their indices, so we can easily get the subarrays.
When we add a number n with an index i we write n as a binary number. We start from the initial node. If the most significant bit of n equals 0, if there exists an edge labelled 0 from our start then we move to a corresponding vertex, if not we create a new edge labelled 0 pointing to a new node, then we move to this newly created one (same thing for 1). Then we keep doing this until we iterated through every bit of n. We add index i to a list of indices in a node that we ended up in.
Make variable prefsum = 0
For each i = 1 to n:
add prefsum to Trie with index i
set prefsum = prefsum ^ array[i]
check if there exists value prefsum in Trie. For each such value v, the subarray of xor equal to 0 is between indices v-th and i-th.
Total complexity is O(n * log(max value in array))
It may not be better than using BST or hash array, but it is a popular trick that especially shines in some problems with XOR operation.
I will write the code blocks in Python 3.7
let l be list of tuples of (i,j)
The most efficient and simple way to deal with is problem is:
Step 1: calculate the xor of prefixes :
xorArr[0] = arr[0] #here arr = [13,8,5,3,3]
for i in range(1, n):
xorArr[i] = xorArr[i - 1] ^ arr[i]
Step 2: Check if at any point xorArr[i]=0, if yes then arr[:i+1] is one subarray whose xor is zero:
for i in range(1, n):
xorArr[i] = xorArr[i - 1] ^ arr[i]
if xorArr[i]==0:
l.append((0,i))
Step 3: Now make a dictionary to store list of indexes of each element occuring in xorArr
d = {xorArr[0]:[0]}
for x in range(1,n):
if xorArr[x] in d.keys():
d[xorArr[x]].append(x)
else:
d[xorArr[x]] = [x]
Step 4: Make a function that will pair up(i,j) for every element in d[xorArr[x]] and add it to l:
from itertools import combinations
def pair_up(arr):
return list(combinations(arr,2))
for x in d.values():
if len(x)==1: #you don't have to worry about elements that occur only once
continue
else: # if same element is present at i and j (i<j) then
l+=pair_up(x) # all pairs of (i,j) are valid (xor(arr[i:j]) = 0)
P.S : You don't have to worry about sorting as all the value in d will obviously be sorted. Hope this Helps.
Do upvote. Cheers!
Edit :
Complexity of code : O(n*((frequency of element with maximum frequency in xorArr) chooses 2)) or O(n*(max_freq C 2)).

Find way to separate array so each subarrays sum is less or equal to a number

I have a mathematical/algorithmic problem here.
Given an array of numbers, find a way to separate it to 5 subarrays, so that sum of each subarrays is less than or equal to a given number. All numbers from the initial array, must go to one of the subarrays, and be part of one sum.
So the input to the algorithm would be:
d - representing the number that each subarrays sum has to be less or equal
A - representing the array of numbers that will be separated to different subarrays, and will be part of one sum
Algorithm complexity must be polynomial.
Thank you.
If by "subarray" you mean "subset" as opposed to "contiguous slice", it is impossible to find a polynomial time algorithm for this problem (unless P = NP). The Partition Problem is to partition a list of numbers into to sets such that the sum of both sets are equal. It is known to be NP-complete. The partition problem can be reduced to your problem as follows:
Suppose that x1, ..., x_n are positive numbers that you want to partition into 2 sets such that their sums are equal. Let d be this common sum (which would be the sum of the xi divided by 2). extend x_i to an array, A, of size n+3 by adding three copies of d. Clearly the only way to partition A into 5 subarrays so that the sum of each is less than or equal to d is if the sum of each actually equals d. This would in turn require 3 of the subarrays to have length 1, each consisting of the number d. The remaining 2 subarrays would be exactly a partition of the original n numbers.
On the other hand, if there are additional constraints on what the numbers are and/or the subarrays need to be, there might be a polynomial solution. But, if so, you should clearly spell out what there constraints are.
Set up of the problem:
d : the upper bound for the subarray
A : the initial array
Assuming A is not sorted.
(Heuristic)
Algorithm:
1.Sort A in ascending order using standard sorting algorithm->O(nlogn)
2.Check if the largest element of A is greater than d ->(constant)
if yes, no solution
if no, continue
3.Sum up all the element in A, denote S. Check if S/5 > d ->O(n)
if yes, no solution
if no, continue
4.Using greedy approach, create a new subarray Asi, add next biggest element aj in the sorted A to Asi so that the sum of Asi does not exceed d. Remove aj from sorted A ->O(n)
repeat step4 until either of the condition satisfied:
I.At creating subarray Asi, there are only 5-i element left
In this case, split the remaining element to individual subarray, done
II. i = 5. There are 5 subarray created.
The algorithm described above is bounded by O(nlogn) therefore in polynomial time.

Find all possible distances from two arrays

Given two sorted array A and B length N. Each elements may contain natural number less than M. Determine all possible distances for all combinations elements A and B. In this case, if A[i] - B[j] < 0, then the distance is M + (A[i] - B[j]).
Example :
A = {0,2,3}
B = {1,2}
M = 5
Distances = {0,1,2,3,4}
Note: I know O(N^2) solution, but I need faster solution than O(N^2) and O(N x M).
Edit: Array A, B, and Distances contain distinct elements.
You can get a O(MlogM) complexity solution in the following way.
Prepare an array Ax of length M with Ax[i] = 1 if i belongs to A (and 0 otherwise)
Prepare an array Bx of length M with Bx[M-1-i] = 1 if i belongs to B (and 0 otherwise)
Use the Fast Fourier Transform to convolve these 2 sequences together
Inspect the output array, non-zero values correspond to possible distances
Note that the FFT is normally done with floating point numbers, so in step 4 you probably want to test if the output is greater than 0.5 to avoid potential rounding noise issues.
I possible done with optimized N*N.
If convert A to 0 and 1 array where 1 on positions which present in A (in range [0..M].
After convert this array into bitmasks, size of A array will be decreased into 64 times.
This will allow insert results by blocks of size 64.
Complexity still will be N*N but working time will be greatly decreased. As limitation mentioned by author 50000 for A and B sizes and M.
Expected operations count will be N*N/64 ~= 4*10^7. It will passed in 1 sec.
You can use bitvectors to accomplish this. Bitvector operations on large bitvectors is linear in the size of the bitvector, but is fast, easy to implement, and may work well given your 50k size limit.
Initialize two bitvectors of length M. Call these vectA and vectAnswer. Set the bits of vectA that correspond to the elements in A. Leave vectAnswer with all zeroes.
Define a method to rotate a bitvector by k elements (rotate down). I'll call this rotate(vect,k).
Then, for every element b of B, vectAnswer = vectAnswer | rotate(vectA,b).

Minimum Complexity of two lists element summation comparison

I have a question in algorithm design about arrays, which should be implement in C language.
Suppose that we have an array which has n elements. For simplicity n is power of '2' like 1, 2, 4, 8, 16 , etc. I want to separate this to 2 parts with (n/2) elements. Condition of separating is lowest absolute difference between sum of all elements in two arrays for example if I have this array (9,2,5,3,6,1,4,7) it will be separate to these arrays (9,5,1,3) and (6,7,4,2) . summation of first array's elements is 18 and the summation of second array's elements is 19 and the difference is 1 and these two arrays are the answer but two arrays like (9,5,4,2) and (7,6,3,1) isn't the answer because the difference of element summation is 4 and we have found 1 . so 4 isn't the minimum difference. How to solve this?
Thank you.
This is the Partition Problem, which is unfortunately NP-Hard.
However, since your numbers are integers, if they are relatively low, there is a pseudo polynomial O(W*n^2) solution using Dynamic Programming (where W is sum of all elements).
The idea is to create the DP matrix of size (W/2+1)*(n+1)*(n/2+1), based on the following recursive formula:
D(0,i,0) = true
D(0,i,k) = false k != 0
D(x,i,k) = false x < 0
D(x,0,k) = false x > 0
D(x,i,0) = false x > 0
D(x,i,k) = D(x,i-1,k) OR D(x-arr[i], i-1,k-1)
The above gives a 3d matrix, where each entry D(x,i,k) says if there is a subset containing exactly k elements, that sums to x, and uses the first i elements as candidates.
Once you have this matrix, you just need to find the highest x (that is smaller than SUM/2) such that D(x,n,n/2) = true
Later, you can get the relevant subset by going back on the table and "retracing" your choices at each step. This thread deals with how it is done on a very similar problem.
For small sets, there is also the alternative of a naive brute force solution, which basically splits the array to all possible halves ((2n)!/(n!*n!) of those), and picks the best one out of them.

find nth-smallest value across m sorted arrays using idea from 2 sorted arrays

May I ask whether would it be possible? the general approach would be somehow like find n-th value on two sorted array, to ignore the insignificants and try to focus on the rest by adjusting the value of n in recursion
The 2 sorted arrays problem would yield a computation time O(log(|A|)+log(|B|), while the question is similar, I would like to ask if there exist algorithm for m sorted arrays for time O(log(|A1|)+log(|A2|)+...+log(|Am|)),
or some similar variation that is near the time I mentioned above (due to the variable m, we might need some other sorting algorithm for the pivots from those arrays),
or if such algorithm doesn't exist, why?
I just can't find this algorithm from googling
There is a simple randomized algorithm:
Select a pivot randomly from any of the m arrays. Let's call it x
For every array, do a binary search for x to find out how many values < x are in the array. Say we have ri values < x in array i. We know that x has rank r = sum(i = 1 to m, ri) in the union of all arrays.
If n <= r, we restrict each array i to the indices 0...(ri - 1) and recurse. If n > r, we restrict each array to the indices ri...|Ai | - 1
repeat
The expected recursion depth is O(log(N)) with N being the total number of elements, with a proof similar to that of Quickselect, so the expected running time is something like O(m * log2(N)).
The paper "Generalized Selection and Ranking" by Frederickson and Johnson proposes selection and ranking algorithms for different scenarios, for example an O(m + c * log(k/c)) algorithm to select the k-th element from m equally sized sorted sequences, with c = min{m, k}.

Resources