Kth element in transformed array - algorithm

I came across this question in recent interview :
Given an array A of length N, we are supposed to answer Q queries. Query form is as follows :
Given x and k, we need to make another array B of same length such that B[i] = A[i] ^ x where ^ is XOR operator. Sort an array B in descending order and return B[k].
Input format :
First line contains interger N
Second line contains N integers denoting array A
Third line contains Q i.e. number of queries
Next Q lines contains space-separated integers x and k
Output format :
Print respective B[k] value each on new line for Q queries.
e.g.
for input :
5
1 2 3 4 5
2
2 3
0 1
output will be :
3
5
For first query,
A = [1, 2, 3, 4, 5]
For query x = 2 and k = 3, B = [1^2, 2^2, 3^2, 4^2, 5^2] = [3, 0, 1, 6, 7]. Sorting in descending order B = [7, 6, 3, 1, 0]. So, B[3] = 3.
For second query,
A and B will be same as x = 0. So, B[1] = 5
I have no idea how to solve such problems. Thanks in advance.

This is solvable in O(N + Q). For simplicity I assume you are dealing with positive or unsigned values only, but you can probably adjust this algorithm also for negative numbers.
First you build a binary tree. The left edge stands for a bit that is 0, the right edge for a bit that is 1. In each node you store how many numbers are in this bucket. This can be done in O(N), because the number of bits is constant.
Because this is a little bit hard to explain, I'm going to show how the tree looks like for 3-bit numbers [0, 1, 4, 5, 7] i.e. [000, 001, 100, 101, 111]
*
/ \
2 3 2 numbers have first bit 0 and 3 numbers first bit 1
/ \ / \
2 0 2 1 of the 2 numbers with first bit 0, have 2 numbers 2nd bit 0, ...
/ \ / \ / \
1 1 1 1 0 1 of the 2 numbers with 1st and 2nd bit 0, has 1 number 3rd bit 0, ...
To answer a single query you go down the tree by using the bits of x. At each node you have 4 possibilities, looking at bit b of x and building answer a, which is initially 0:
b = 0 and k < the value stored in the left child of the current node (the 0-bit branch): current node becomes left child, a = 2 * a (shifting left by 1)
b = 0 and k >= the value stored in the left child: current node becomes right child, k = k - value of left child, a = 2 * a + 1
b = 1 and k < the value stored in the right child (the 1-bit branch, because of the xor operation everything is flipped): current node becomes right child, a = 2 * a
b = 1 and k >= the value stored in the right child: current node becomes left child, k = k - value of right child, a = 2 * a + 1
This is O(1), again because the number of bits is constant. Therefore the overall complexity is O(N + Q).
Example: [0, 1, 4, 5, 7] i.e. [000, 001, 100, 101, 111], k = 3, x = 3 i.e. 011
First bit is 0 and k >= 2, therefore we go right, k = k - 2 = 3 - 2 = 1 and a = 2 * a + 1 = 2 * 0 + 1 = 1.
Second bit is 1 and k >= 1, therefore we go left (inverted because the bit is 1), k = k - 1 = 0, a = 2 * a + 1 = 3
Third bit is 1 and k < 1, so the solution is a = 2 * a + 0 = 6
Control: [000, 001, 100, 101, 111] xor 011 = [011, 010, 111, 110, 100] i.e. [3, 2, 7, 6, 4] and in order [2, 3, 4, 6, 7], so indeed the number at index 3 is 6 and the solution (always talking about 0-based indexing here).

Related

Find greater number form self in left side and smaller number form self in right side

Consider an array a of n integers, indexed from 1 to n.
For every index i such that 1<i<n, define:
count_left(i) = number of indices j such that 1 <= j < i and a[j] > a[i];
count_right(i) = number of indices j such that i < j <= n and a[j] < a[i];
diff(i) = abs(count_left(i) - count_right(i)).
The problem is: given array a, find the maximum possible value of diff(i) for 1 < i < n.
I got solution by brute force. Can anyone give better solution?
Constraint: 3 < n <= 10^5
Example
Input Array: [3, 6, 9, 5, 4, 8, 2]
Output: 4
Explanation:
diff(2) = abs(0 - 3) = 3
diff(3) = abs(0 - 4) = 4
diff(4) = abs(2 - 2) = 0
diff(5) = abs(3 - 1) = 2
diff(6) = abs(1 - 1) = 0
maximum is 4.
O(nlogn) approach:
Walk through array left to right and add every element to augmented binary search tree (RB, AVL etc) containing fields of subtree size, initial index and temporary rank field. So immediately after adding we know rank of element in the current tree state.
lb = index - temprank
is number of left bigger elements - remember it in temprank field.
After filling the tree with all items traverse tree again, retrieving final element rank.
rs = finalrank - temprank
is number of right smaller elements. Now just get abs of difference of lb and rs
diff = abs(lb - rs) = abs(index - temprank - finalrank + temprank ) =
abs(index - finalrank)
But ... we can see that we don't need temprank at all.
Moreover - we don't need binary tree!
Just perform sorting of pairs (element; initial index) by element key and get max absolute difference of new_index - old_index (except for old indices 1 and n)
a 3, 6, 9, 5, 4, 8, 2
old 2 3 4 5 6
new 5 7 4 3 6
dif 3 4 0 2 0
Python code for concept checking
a = [3, 6, 9, 5, 4, 8, 2]
b = sorted([[e,i] for i,e in enumerate(a)])
print(b)
print(max([abs(n-o[1]) if 0<o[1]<len(a)-1 else 0 for n,o in enumerate(b)]))

Finding the maximum possible sum/product combination of integers

Given an input of a list of N integers always starting with 1, for example: 1, 4, 2, 3, 5. And some target integer T.
Processing the list in order, the algorithm decides whether to add or multiply the number by the current score to achieve the maximum possible output < T.
For example: [input] 1, 4, 2, 3, 5 T=40
1 + 4 = 5
5 * 2 = 10
10 * 3 = 30
30 + 5 = 35 which is < 40, so valid.
But
1 * 4 = 4
4 * 2 = 8
8 * 3 = 24
24 * 5 = 120 which is > 40, so invalid.
I'm having trouble conceptualizing this in an algorithm -- I'm just looking for advice on how to think about it or at most pseudo-code. How would I go about coding this?
My first instinct was to think about the +/* as 1/0, and then test permutations like 0000 (where length == N-1, I think), then 0001, then 0011, then 0111, then 1111, then 1000, etc. etc.
But I don't know how to put that into pseudo-code given a general N integers. Any help would be appreciated.
You can use recursive to implement the permutations. Python code below:
MINIMUM = -2147483648
def solve(input, T, index, temp):
# if negative value exists in input, remove below two lines
if temp >= T:
return MINIMUM
if index == len(input):
return temp
ans0 = solve(input, T, index + 1, temp + input[index])
ans1 = solve(input, T, index + 1, temp * input[index])
return max(ans0, ans1)
print(solve([1, 4, 2, 3, 5], 40, 1, 1))
But this method requires O(2^n) time complexity.

algorithmic puzzle for calculating the number of combinations of numbers sum to a fixed result

This is a puzzle i think of since last night. I have come up with a solution but it's not efficient so I want to see if there is better idea.
The puzzle is this:
given positive integers N and T, you will need to have:
for i in [1, T], A[i] from { -1, 0, 1 }, such that SUM(A) == N
additionally, the prefix sum of A shall be [0, N], while when the prefix sum PSUM[A, t] == N, it's necessary to have for i in [t + 1, T], A[i] == 0
here prefix sum PSUM is defined to be: PSUM[A, t] = SUM(A[i] for i in [1, t])
the puzzle asks how many such A's exist given fixed N and T
for example, when N = 2, T = 4, following As work:
1 1 0 0
1 -1 1 1
0 1 1 0
but following don't:
-1 1 1 1 # prefix sum -1
1 1 -1 1 # non-0 following a prefix sum == N
1 1 1 -1 # prefix sum > N
following python code can verify such rule, when given N as expect and an instance of A as seq(some people may feel easier reading code than reading literal description):
def verify(expect, seq):
s = 0
for j, i in enumerate(seq):
s += i
if s < 0:
return False
if s == expect:
break
else:
return s == expect
for k in range(j + 1, len(seq)):
if seq[k] != 0:
return False
return True
I have coded up my solution, but it's too slow. Following is mine:
I decompose the problem into two parts, a part without -1 in it(only {0, 1} and a part with -1.
so if SOLVE(N, T) is the correct answer, I define a function SOLVE'(N, T, B), where a positive B allows me to extend prefix sum to be in the interval of [-B, N] instead of [0, N]
so in fact SOLVE(N, T) == SOLVE'(N, T, 0).
so I soon realized the solution is actually:
have the prefix of A to be some valid {0, 1} combination with positive length l, and with o 1s in it
at position l + 1, I start to add 1 or more -1s and use B to track the number. the maximum will be B + o or depend on the number of slots remaining in A, whichever is less.
recursively call SOLVE'(N, T, B)
in the previous N = 2, T = 4 example, in one of the search case, I will do:
let the prefix of A be [1], then we have A = [1, -, -, -].
start add -1. here i will add only one: A = [1, -1, -, -].
recursive call SOLVE', here i will call SOLVE'(2, 2, 0) to solve the last two spots. here it will return [1, 1] only. then one of the combinations yields [1, -1, 1, 1].
but this algorithm is too slow.
I am wondering how can I optimize it or any different way to look at this problem that can boost the performance up?(I will just need the idea, not impl)
EDIT:
some sample will be:
T N RESOLVE(N, T)
3 2 3
4 2 7
5 2 15
6 2 31
7 2 63
8 2 127
9 2 255
10 2 511
11 2 1023
12 2 2047
13 2 4095
3 3 1
4 3 4
5 3 12
6 3 32
7 3 81
8 3 200
9 3 488
10 3 1184
11 3 2865
12 3 6924
13 3 16724
4 4 1
5 4 5
6 4 18
an exponential time solution will be following in general(in python):
import itertools
choices = [-1, 0, 1]
print len([l for l in itertools.product(*([choices] * t)) if verify(n, l)])
An observation: assuming that n is at least 1, every solution to your stated problem ends in something of the form [1, 0, ..., 0]: i.e., a single 1 followed by zero or more 0s. The portion of the solution prior to that point is a walk that lies entirely in [0, n-1], starts at 0, ends at n-1, and takes fewer than t steps.
Therefore you can reduce your original problem to a slightly simpler one, namely that of determining how many t-step walks there are in [0, n] that start at 0 and end at n (where each step can be 0, +1 or -1, as before).
The following code solves the simpler problem. It uses the lru_cache decorator to cache intermediate results; this is in the standard library in Python 3, or there's a recipe you can download for Python 2.
from functools import lru_cache
#lru_cache()
def walks(k, n, t):
"""
Return the number of length-t walks in [0, n]
that start at 0 and end at k. Each step
in the walk adds -1, 0 or 1 to the current total.
Inputs should satisfy 0 <= k <= n and 0 <= t.
"""
if t == 0:
# If no steps allowed, we can only get to 0,
# and then only in one way.
return k == 0
else:
# Count the walks ending in 0.
total = walks(k, n, t-1)
if 0 < k:
# ... plus the walks ending in 1.
total += walks(k-1, n, t-1)
if k < n:
# ... plus the walks ending in -1.
total += walks(k+1, n, t-1)
return total
Now we can use this function to solve your problem.
def solve(n, t):
"""
Find number of solutions to the original problem.
"""
# All solutions stick at n once they get there.
# Therefore it's enough to find all walks
# that lie in [0, n-1] and take us to n-1 in
# fewer than t steps.
return sum(walks(n-1, n-1, i) for i in range(t))
Result and timings on my machine for solve(10, 100):
In [1]: solve(10, 100)
Out[1]: 250639233987229485923025924628548154758061157
In [2]: %timeit solve(10, 100)
1000 loops, best of 3: 964 µs per loop

How would I convert a number represented as an array of digits from base-2^k to binary?

I have an algorithm that can simulate converting a binary number to a decimal number by hand. What I mean by this is that each number is represented as an array of digits (from least-to-most-significant) rather than using a language's int or bigint type.
For example, 42 in base-10 would be represented as [2, 4], and 10111 in base-2 would be [1, 1, 1, 0, 1].
Here it is in Python.
def double(decimal):
result = []
carry = 0
for i in range(len(decimal)):
result.append((2 * decimal[i] + carry) % 10)
carry = floor((2 * decimal[i] + carry) / 10)
if carry != 0:
result.append(carry)
return result
def to_decimal(binary):
decimal = []
for i in reversed(range(len(binary))):
decimal = double(decimal)
if binary[i]:
if decimal == []:
decimal = [1]
else:
decimal[0] += 1
return decimal
This was part of an assignment I had with an algorithms class a couple of semesters ago, and he gave us a challenge in his notes claiming that we should be able to derive from this algorithm a new one that could convert a number from base-2^k to binary. I dug this up today and it's been bothering me (read: making me feel really rusty), so I was hoping someone would be able to explain how I would write a to_binary(number, k) function based on this algorithm.
Base 2^k has digits 0, 1, ..., 2^k - 1.
For example, in base 2^4 = 16, we'd have the digits 0, 1, 2, ..., 10, 11, 12, 13, 14, 15. For convenience, we use letters for the bigger digits: 0, 1, ..., A, B, C, D, E, F.
So let's say you want to convert AB to binary. The trivial thing to do is convert it to decimal first, since we know how to convert decimal to binary:
AB = B*16^0 + A*16^1
= 11*16^0 + 10*16^1
= 171
If you convert 171 to binary, you'll get:
10101011
Now, is there a shortcut we can use, so we don't go through base 10? There is.
Let's stop at this part:
AB = B*16^0 + A*16^1
= 11*16^0 + 10*16^1
And recall what it takes to convert from decimal to binary: do integer division by 2, write down the remainders, write the remainders in reverse order in the end:
number after integer division by 2 | remainder after integer division by 2
--------------------------------------------------------------------------
5 | 1
2 | 0
1 | 1
0 |
=> 5 = reverse(101) = 101 in binary
Let's apply that to this part:
11*16^0 + 10*16^1
First of all, for the first 4 (because 16^1 = 2^4) divisions, the remainder of division by 2 will only depend on 11, because 16 % 2 == 0.
11 | 1
5 | 1
2 | 0
1 | 1
0 |
So the last part of our number in binary will be:
1011
By the time we've done this, we will have gotten rid of the 16^1, since we've done 4 divisions so far. So now we only depend on 10:
10 | 0
5 | 1
2 | 0
1 | 1
0 |
So our final result will be:
10101011
Which is what we got with the classic approach!
As we can notice, we only need to convert the digits to binary individually, because they are what will, individually and sequentially, affect the result:
A = 10 = 1010
B = 11 = 1011
=> AB in binary = 10101011
For your base 2^k, do the same: convert each individual digit to binary, from most significant to least, and concatenate the results in order.
Example implementation:
def to_binary(number, k):
result = []
for x in number:
# convert x to binary
binary_x = []
t = x
while t != 0:
binary_x.append(t % 2)
t //= 2
result.extend(binary_x[::-1])
return result
#10 and 11 are digits here, so this is like AB.
print(to_binary([10, 11], 2**4))
print(to_binary([101, 51, 89], 2**7))
Prints:
[1, 0, 1, 0, 1, 0, 1, 1]
[1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1]
Note: there is actually a bug in the above code. For example, 2 in base 2**7 will get converted to 10 in binary. But digits in base 2**7 should have 7 bits, so you need to pad it to that many bits: 0000010. I'll leave this as an exercise.

Maximize the sum of product of adjacent numbers

Here is a question that I encountered during an Interviewstreet codesprint.
I was unable to find a a solution or even think in its direction. I'd be thankful if someone could help me find the soultion, or explain me how the problem neeeds to be dealt with.
Given numbers 1, 2, 3, .., N, arrange them in a order such that the
sum of product of adjecent numbers is maximized.
For example: if N = 3, and we order them as ( 1, 2, 3 ), the sum of
products is 1*2 + 2*3 = 8 and if we order them as ( 1, 3 ,2 ) the sum
of products is 1*3 + 3*2 = 9.
Input format :
First line of the input contains T, the number of test-cases. Then
follow T lines, each containing an integer N.
Output format :
For each test case print the maximum sum of product of adjacent
numbers.
Sample input :
2 2 4
Sample output :
2 23
Explanation :
In first test case given permutation is ( 1, 2 ). So maximum sum of
product is 1*2. In Second test case the numbers are (1,2,3,4).
Arrangement 1,3,4,2 has sum of product of adjacent numbers as
1*3+3*4+4*2 = 23. No other arrange has sum of product of adjacent
numbers more than 23.
Constraints :
1 <= T <= 10 1 <= N <= 200000
The maximum sum-of-adjacent-products comes when the largest value is in the middle of the sequence, and the successively lower values alternate to its left and right. That is, your sequence for a given value n would be [..., n-3, n-1, n, n-2, n-4, ...] (or the reverse of this, which will have the same sum of products).
So, leaving out the input-parsing bits, here's the heart of the algorithm (in Python, but easily translated to other languages):
def maximumSumOfAdjacentProducts(n):
if n == 1: # special case needed for a one element sequence
return 1
sumOfProducts = n * (n-1) # this pair is the "center" of the sequence
for i in range(n-2, 0, -1): # iterate downward from n-2 to 1
sumOfProducts += i*(i+2) # each adjacent pair is separated by 2
return sumOfProducts
Sort the array, call it sortedArray in ascending order.
Remove max1, max2 and put them in a result list.
Remove the next element and add it to the side of MAX(max1, max2).
Update max1 and max2. i.e. max1 is left side and max2 is right side of the list.
Repeat steps 3 & 4 until the sorted input array has elements.
Example:
inputArray: 1,3,4,2,5
sortedArray: 1,2,3,4,5
Add 5 and 4 to the list first.
result = [5, 4]
Remove 3 and add it to MAX(5,4)
result = [3, 5, 4]
Remove 2 and add it to MAX(3,4)
result = [3, 5, 4, 2]
Remove 1 and add it to MAX(3,2)
result = [1, 3, 5, 4, 2]

Resources