Binary tree optimize solution? - algorithm

Got this problem in one of the coding contest . Do you have a better approach than mine . I have given the pseudocode below
Given a complete binary tree with nodes of values of either 1 or 0, the following rules always hold:
a node's value is 1 if and only if all its subtree nodes' values are 1
a leaf node can have value either 1 or 0
Implement the following 2 APIs:
set_bit(offset, length), set the bits at range from offset to offset+length-1 on the leaf nodes
clear_bit(offset, length), clear the bits at range from offset to offset+length-1 on the leaf nodes
i.e. The tree is like:
0
/ \
0 1
/ \ / \
0 1 1 1
/\ / \ / \ / \
0 1 1 1 1 1 1 1
Input will given in 2 D array
int arr[][] = [ [0],[0,1],[1,0,1,0],[1,1,1,0,1,1,1,1]]
we need to set the bit or clear bit on the leaf nodes. In the above example if I do
clear(3,5)
i.e. The tree would be like:
0
/ \
0 0
/ \ / \
0 0 0 0
/\ / \ / \ / \
0 1 1 0 0 0 0 0
Pseudocode : My approach
1] Go to the last row and inner loop starts at offset on the leaf node (last row + offset).
2] check for the element at the offset if it is 1
3] if sibling zero the ancestor is zero no further action else if it is one
4] note down the range of the ancestor to zero in our case
(ancestor is row-- and column/2) so in our case for row 2 (range is column 1 to 3)
5]next iteration row 2 and the inner loop will move from column 1 to 3
6] keep repeating
For set bit as well we can for a similar approach

Related

How to find all sub rectangles using fastest algorithm?

An example , suppose we have a 2D array such as:
A= [
[1,0,0],
[1,0,0],
[0,1,1]
]
The task is to find all sub rectangles concluding only zeros. So the output of this algorithm should be:
[[0,1,0,2] , [0,1,1,1] , [0,2,1,2] , [0,1,1,2] ,[1,1,1,2], [2,0,2,0] ,
[0,1,0,1] , [0,2,0,2] , [1,1,1,1] , [1,2,1,2]]
Where i,j in [ i , j , a , b ] are coordinates of rectangle's starting point and a,b are coordinates of rectangle's ending point.
I found some algorithms for example Link1 and Link2 but I think first one is simplest algorithm and we want fastest.For the second one we see that the algorithm only calculates rectangles and not all sub rectangles.
Question:
Does anyone know better or fastest algorithm for this problem? My idea is to use dynamic programming but how to use isn't easy for me.
Assume an initial array of size c columns x r rows.
Every 0 is a rectangle of size 1x1.
Now perform an "horizontal dilation", i.e. replace every element by the maximum of itself and the one to its right, and drop the last element in the row. E.g.
1 0 0 1 0
1 0 0 -> 1 0
0 1 1 1 1
Every zero now corresponds to a 1x2 rectangle in the original array. You can repeat this c-1 times, until there is a single column left.
1 0 0 1 0 1
1 0 0 -> 1 0 -> 1
0 1 1 1 1 1
The zeroes correspond to a 1xc rectangles in the original array (initially c columns).
For every dilated array, perform a similar "vertical dilation".
1 0 0 1 0 1
1 0 0 -> 1 0 -> 1
0 1 1 1 1 1
| | |
V V V
1 0 0 1 0 1
1 1 1 -> 1 1 -> 1
| | |
V V V
1 1 1 -> 1 1 -> 1
In these rxc arrays, the zeroes correspond to the subrectangles of all possible sizes. (Here, 5 of size 1x1, 2 of size 2x1, 2 of size 1x2 and one of size 2x2.)
The total workload to detect the zeroes and compute the dilations is of order O(c²r²). I guess that this is worst-case optimal. (In case an array contains no zeroes, there is no need to continue any dilation.)

Check if a number is divisible by 3 in logic design

i seen a post on the site about it and i didn't understand the answer, can i get explanation please:
question:
Write code to determine if a number is divisible by 3. The input to the function is a single bit, 0 or 1, and the output should be 1 if the number received so far is the binary representation of a number divisible by 3, otherwise zero.
Examples:
input "0": (0) output 1
inputs "1,0,0": (4) output 0
inputs "1,1,0,0": (6) output 1
This is based on an interview question. I ask for a drawing of logic gates but since this is stackoverflow I'll accept any coding language. Bonus points for a hardware implementation (verilog etc).
Part a (easy): First input is the MSB.
Part b (a little harder): First input is the LSB.
Part c (difficult): Which one is faster and smaller, (a) or (b)? (Not theoretically in the Big-O sense, but practically faster/smaller.) Now take the slower/bigger one and make it as fast/small as the faster/smaller one.
answer:
State table for LSB:
S I S' O
0 0 0 1
0 1 1 0
1 0 2 0
1 1 0 1
2 0 1 0
2 1 2 0
Explanation: 0 is divisible by three. 0 << 1 + 0 = 0. Repeat using S = (S << 1 + I) % 3 and O = 1 if S == 0.
State table for MSB:
S I S' O
0 0 0 1
0 1 2 0
1 0 1 0
1 1 0 1
2 0 2 0
2 1 1 0
Explanation: 0 is divisible by three. 0 >> 1 + 0 = 0. Repeat using S = (S >> 1 + I) % 3 and O = 1 if S == 0.
S' is different from above, but O works the same, since S' is 0 for the same cases (00 and 11). Since O is the same in both cases, O_LSB = O_MSB, so to make MSB as short as LSB, or vice-versa, just use the shortest of both.
thanks for the answers in advanced.
Well, I suppose the question isn't entirely off-topic, since you asked about logic design, but you'll have to do the coding yourself.
You have 3 states in the S column. These track the value of the current full input mod 3. So, S0 means the current input mod 3 is 0, and so is divisible by 0 (remember also that 0 is divisible by 3). S1 means the remainder is 1, S2 means that the remainder is 2.
The I column gives the current input (0 or 1), and S' gives the next state (in other words, the new number mod 3).
For 'LSB', the new number is the old number << 1, plus either 0 or 1. Write out the table. For starters, if the old modulo was 0, then the new modulo will be 0 if the input bit was 0, and will be 1 if the new input was 1. This gives you the first 2 rows in the first table. Filling in the rest is left as an exercise for you.
Note that the O column is just 1 if the next state is 0, as expected.

BIT Making in permutation generation

I am learning about TSP and understand it quite well , but i could not understand How Bit masking can be used to generate all permutation.
If i am 3 citites so i will find the cost as:
0 1 2 3
0 1 3 2
0 2 1 3
0 2 3 1
0 3 1 2
0 3 2 1
or:
g(0,{1,2,3})
/ | \
g(1,{2,3}) g(2,{1,3}) g(3,{1,2})
/ \ / \ | \
g(2,{3}) g(3,{2}) g(1,{3}) g(3,{1}) g(1,{2}) g(2,{1})
/ | | | | |
0 0 0 0 0 0
g(3,null) g(2,null) g(3,null) g(1,null) g{2,null) g(1,null)
How bit masking is used in this
Here is a dynamic programming solution with O(2^n * n^2) time and O(2^n * n) space complexity which uses bit masks.
Let's assume that f(mask, last) is the shortest path that goes for all cities in the mask which starts in 0 city and ends in the last city(last must be in the mask).
The base case is simple: f(1, 0) = 0(it corresponds to the case when the only city we have visited so far is the start city).
Transitions:
for cur not in mask
for last = 0 ... n - 1
f(mask or 2^cur, cur) = min(f(mask or 2^cur, cur), f(mask, last) + dist(last, cur))
The answer is min(f(2^n - 1, last) + dist(last, 0) for last = 1 ... n - 1)

converting sequences to lex order

I have a function that generates binary sequences with a fixed number of 1's (the rest are 0's). I need a function that takes a sequences and returns the position of that sequence in lexicographic order. For example, the 10 sequences of length 5 with 3 1's are
0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
0 1 1 1 0
1 0 0 1 1
1 0 1 0 1
1 0 1 1 0
1 1 0 0 1
1 1 0 1 0
1 1 1 0 0
I need a function that takes, for example 0 1 1 0 1 and returns 3 since it's the third in the list.
The only thing I can think of, which is way too inefficient, is to generate all of the sequences (easy), store them (takes too much space), then search for the given sequence in the list (too slow), and return its position. Is there a faster way to do this? Some easy trick that I don't see?
We call the set of sequences of length n with k 1's binseq(n,k). This problem can then be solved recursively, as follows:
Base case: If S has length 1, it's in position 1.
If S starts with a 0, its position is the same as the position of tail(S) (S with the first element removed) in binseq(n-1, k).
If S starts with a 1, its position is equal to the position of tail(S) in binseq(n-1, k-1) plus the number of sequences in binseq(n-1, k).
In python code:
#!/usr/bin/env python
def binom(n, k):
result = 1
for i in range(1, k+1):
result = result * (n-i+1) / i
return result
def lexpos(seq):
if len(seq) == 1:
return 1
elif seq[0] == 0:
return lexpos(seq[1:])
else:
return binom(len(seq)-1, seq.count(1)) + lexpos(seq[1:])
Or the iterative version, as suggested by Abhishek Bansal:
def lexpos_iter(seq):
pos = 1
for i in xrange(len(seq)):
if seq[i] == 1:
pos += binom(len(seq)-i-1, seq[i:].count(1))
return pos

permutation matrix

Is it possible to decompose a matrix A having n rows and n columns to sum of m [n x n] permutation matrices. where m is the number of 1's in each row and each column in matrix A?
UPDATE:
yes, this is possible. I came across such an exmaple which is shown below - but How can we generalize the answer?
What you want is called a 1-factorization. One algorithm is repeatedly to find a perfect matching and remove it; probably there are others.
For the first permutation matrix, take the first 1 in the first row. For the second row, take the first 1 that is in a column you don't already have. For the third row, take the first 1 that is in a column you don't already have. And so on. Do this for all rows.
You now have one permutation matrix.
Next subtract your first permutation matrix from the original. This new matrix now has m-1 ones in each row and column. So repeat the process m-1 more times, and you'll have your m permutation matrices.
You can skip the last step, because a matrix with one 1 in each row and column already is a permutation matrix. There's no need to do any calculations.
This is a greedy algorithm that doesn't always work. We can make it work by changing the selection rule slightly. See below:
For your example:
1 0 1 1
A = 1 1 0 1
1 1 1 0
0 1 1 1
In the first step, we pick (1,1) for the first row, (2,2) for the second row, (3,3) for the thrid row and (4,4) for the 4th row. We then have:
1 0 0 0 0 0 1 1
A = 0 1 0 0 + 1 0 0 1
0 0 1 0 1 1 0 0
0 0 0 1 0 1 1 0
The first matrix is a permutation matrix. The second matrix has exactly two 1's in each row and column. So we pick, in order: (1,3), (2,1), (3,2) and... we're in trouble: the rows that contain a 1 in column 4 have already been used.
So how do we fix this? Well, we can keep track of the number of 1's remaining in each column. Instead of picking the first column that is unused, we pick the column with the lowest number of 1's remaining. For the second matrix above:
0 0 1 1 0 0 X 0 0 0 X 0 0 0 X 0
B = 1 0 0 1 --> 1 0 0 1 --> 0 0 0 X --> 0 0 0 X
1 1 0 0 1 1 0 0 1 1 0 0 X 0 0 0
0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0
------- ------- ------- -------
2 2 2 2 2 2 X 1 1 2 X X X 1 X X
So we would pick column 4 in the second step, column 1 in the 3rd step, and column 2 in the 4th step.
There can always be only one column with one remaining 1. The other 1's must have been taken away in m-1 previous rows. If you had two such columns, one of them would have had to have been picked as the minimum column before.
This can be done easily using a recursive (backtracking OR depth-first traversal) algorithm. Here is the pseudo-code for its solution:
void printPermutationMatrices(const int OrigMat[][], int permutMat[], int curRow, const int n){
//curPermutMatrix is 1-D array where value of ith element contains the value of column where 1 is placed in ith row
if(curRow == n){//Base case
//do stuff with permutMat[]
printPermutMat(permutMat);
return;
}
for(int col=0; col<n; col++){//try to place 1 in cur_row in each col if possible and go further to next row in recursion
if(origM[cur_row][col] == 1){
permutMat[cur_row] = col;//choose this col for cur_row
if there is no conflict to place a 1 in [cur_row, col] in permutMat[]
perform(origM, curPermutMat, curRow+1, n);
}
}
}
Here is how to call from your main function:
int[] permutMat = new int[n];
printPermutationMatrices(originalMatrix, permutMat, 0, n);

Resources