Find number of nodes in left and right subtree of a complete binary tree if total number of nodes are given in O(1) - binary-tree

I want to find count of nodes in left and right subtree of complete binary tree if total nodes are given,
for example,
n = 5
===> left -> 3 right -> 1
n = 8
===> left -> 4 right -> 3
where n is total number of nodes in a binary tree
is there any formula or O(1)/optimal solution to do this?

is there any formula or O(1)/optimal solution to do this?
Yes.
Write the given 𝑛 (number of nodes) in binary notation, and turn every 1 to a 0, except the most significant 1. Call this number 𝑝. Define 𝑘 as 𝑛 − 𝑝, so that in binary it is the same as 𝑛, but with its most significant digit removed. The number of nodes in the right subtree wil be equal to max(𝑘, 𝑝 / 2 − 1).
It is then a piece of cake to know how many are in the left subtree, because the sum of nodes in both subtrees plus 1 (for the root node) must be equal to 𝑛.
Your example
When 𝑛 = 5, we note that down in binary as 0b101. We can see that 𝑝 = 0b100 and 𝑘 = 0b001. So the right subtree has max(𝑘, 𝑝/2 − 1) nodes, i.e. max(1, 1) = 1. The left subtree has the remaining nodes, i.e. 3, so that 3 + 1 + 1 (for root) = 5.
Other examples
Here is a table with the results for 𝑛 between 1 and 15:
𝑛
in binary
𝑝
𝑘
𝑝/2 − 1
in right subtree = max(𝑘, 𝑝/2 − 1)
in left subtree
1
0b1
0b1
0b0
0b0
0
0
2
0b10
0b10
0b0
0b0
0
1
3
0b11
0b10
0b1
0b1
1
1
4
0b100
0b100
0b00
0b1
1
2
5
0b101
0b100
0b01
0b1
1
3
6
0b110
0b100
0b10
0b1
2
3
7
0b111
0b100
0b11
0b1
3
3
8
0b1000
0b1000
0b000
0b11
3
4
9
0b1001
0b1000
0b001
0b11
3
5
10
0b1010
0b1000
0b010
0b11
3
6
11
0b1011
0b1000
0b011
0b11
3
7
12
0b1100
0b1000
0b100
0b11
4
7
13
0b1101
0b1000
0b101
0b11
5
7
14
0b1110
0b1000
0b110
0b11
6
7
15
0b1111
0b1000
0b111
0b11
7
7

Related

Generic triangular numbers sequence formula

I know that I can get the nth element of the following sequence
1 3 6 10 15 21
With the formula
(n * (n + 1)) / 2
where n is the nth number I want. How can I generalise the formula to get the nth element of the following sequences where by following sequences I mean
1 -> 1 3 6 10 15 21
2 -> 2 5 9 14 20
3 -> 4 8 13 19
4 -> 7 12 18
5 -> 11 17
6 -> 16
It is not quite clear what do you mean by n-th element in 2D-table (potentially infinite)
Simple formula for element at row and column (numbered from 1):
(r+c-1)*(r+c)/2 - (r-1)
Possible intuition for this formula:
Key moment: element with coordinates r,c stands on the diagonal number d, where d = r + c - 1
There are s = d*(d+1)/2 elements in d filled diagonals, so the last element of d-th diagonal (rightmost top) has value s, and element in r-th row of the same diagonal is
v(r,c) = s-(r-1) = (d)*(d+1)/2 -(r-1) = (r+c-1)*(r+c)/2 - (r-1)

Check if a road is available in something similar to a binary tree

I have a coordinates system which looks like that http://i.imgur.com/oKCU2uv.png Where the points -> (depthToNode, Node). But I don't have this structure, just raw points. You can go from (x,y) only to (x+1,y+1) or (x+1,y-1).
The data I get is a n < 500000, n - number of 'pillars' with blocked points. Then for each n I get x, a, b which are: x - the x coord of the pillar, a - everyone y coord <= a is blocked, b - everyone y coord >= b is blocked. The next x is always greater than the previous one. For Example: (x,a,b) -> (4,0,5). Then I know that the not blocked points on x = 4 are (4,2),(4,4). Note that if x is even then y must be also even, otherwise we can't go through such a point, for example (4,1), (4,3).
I noticed that if our coordinates are like (s,m) and I want to go to (c,d) then if c+d-s-m >= 0 then I can get from point (s,m) to (c,d). But the problem is that if I get 500000 'pillars' with blocked points, and the points are blocked from y < -10^8 and y > 10^8 then there is a large amount of points to check.
So the question is: How can I check if I can go from point (0,0) to the one of the points (x,y) avoiding the points which are blocking the path. (x,y) are all the points not blocked in the last 'pillar'
EXAMPLE 1:
INPUT:
4
1 0 2
4 -5 3
5 1 3
8 2 5
OUTPUT: NO
EXAMPLE 2:
INPUT:
4
1 0 2
4 3 5
5 -1000 3000
8 1 98
OUTPUT: YES
There is no need to check all possible nodes.
For each step of tree culling we only need to keep 2 values: min and max nodes that survived this step at its base level N. Let`s call them LN and UN, respectively.
Given the range [LN; UN] we can easily find [LN+K; UN+K] for any natural K.
Now we choose K so that N + K = N`, i.e. the level where the next step of culling is to be performed. We already know [LN`; UN`], see above. And now we compute [L`N`; U`N`] — the range of values that actually survived this next step at level N`.
Intersect these two ranges and repeat.
Proceed until either [LN`; UN`] ∩ [L`N`; U`N`] = ∅ (in which case the answer`s NO) or there is no more data left (the answer`s YES).
Illustration:
0
-1 1
-2 0 2
-3 -1 1 3
-4 -2 0 2 4
-5 -3 -1 1 3 5
-6 -4 -2 0 2 4 6
-7 -5 -3 -1 1 3 5 7
-8 -6 -4 -2 0 2 4 6 8
0
1 ← #1 (1: 0, 2)
0 2
-1 1 3
-2_____0_____2_____4_
-3 -1 1 3 5
-4 -2 0 2 4 6
-5 -3 -1 1 3 5 7
-6 -4 -2 0 2 4 6 8
0
1 ← #1 (1: 0, 2)
0 2
-1 1 3
4 ← #2 (4: 3, 5)
_3_____5_
2 4 6
1 3 5 7
0 2 4 6 8
0
1 ← #1 (1: 0, 2)
0 2
-1 1 3
4 ← #2 (4: 3, 5)
3 5 ← #3 (5: –1000, 3000)
2 4 6
1 3 5 7
_0_____2_____4_____6_____8_
0
1 ← #1 (1: 0, 2)
0 2
-1 1 3
4 ← #2 (4: 3, 5)
3 5 ← #3 (5: –1000, 3000)
2 4 6
1 3 5 7
2 4 6 8 ← #4 (8: 1, 98)

Efficiently construct a square matrix with unique numbers in each row

A matrix of size nxn needs to be constructed with the desired properties.
n is even. (given as input to the algorithm)
Matrix should contain integers from 0 to n-1
Main diagonal should contain only zeroes and matrix should be symmetric.
All numbers in each row should be different.
For various n , any one of the possible output is required.
input
2
output
0 1
1 0
input
4
output
0 1 3 2
1 0 2 3
3 2 0 1
2 3 1 0
Now the only idea that comes to my mind is to brute-force build combinations recursively and prune.
How can this be done in a iterative way perhaps efficiently?
IMO, You can handle your answer by an algorithm to handle this:
If 8x8 result is:
0 1 2 3 4 5 6 7
1 0 3 2 5 4 7 6
2 3 0 1 6 7 4 5
3 2 1 0 7 6 5 4
4 5 6 7 0 1 2 3
5 4 7 6 1 0 3 2
6 7 4 5 2 3 0 1
7 6 5 4 3 2 1 0
You have actually a matrix of two 4x4 matrices in below pattern:
m0 => 0 1 2 3 m1 => 4 5 6 7 pattern => m0 m1
1 0 3 2 5 4 7 6 m1 m0
2 3 0 1 6 7 4 5
3 2 1 0 7 6 5 4
And also each 4x4 is a matrix of two 2x2 matrices with a relation to a power of 2:
m0 => 0 1 m1 => 2 3 pattern => m0 m1
1 0 3 2 m1 m0
In other explanation I should say you have a 2x2 matrix of 0 and 1 then you expand it to a 4x4 matrix by replacing each cell with a new 2x2 matrix:
0 => 0+2*0 1+2*0 1=> 0+2*1 1+2*1
1+2*0 0+2*0 1+2*1 0+2*1
result => 0 1 2 3
1 0 3 2
2 3 0 1
3 2 1 0
Now expand it again:
0,1=> as above 2=> 0+2*2 1+2*2 3=> 0+2*3 1+2*3
1+2*2 0+2*2 1+2*3 0+2*3
I can calculate value of each cell by this C# sample code:
// i: row, j: column, n: matrix dimension
var v = 0;
var m = 2;
do
{
var p = m/2;
v = v*2 + (i%(n/p) < n/m == j%(n/p) < n/m ? 0 : 1);
m *= 2;
} while (m <= n);
We know each row must contain each number. Likewise, each row contains each number.
Let us take CS convention of indices starting from 0.
First, consider how to place the 1's in the matrix. Choose a random number k0, from 1 to n-1. Place the 1 in row 0 at position (0,k0). In row 1, if k0 = 1 in which case there is already a one placed. Otherwise, there are n-2 free positions and place the 1 at position (1,k1). Continue in this way until all the 1 are placed. In the final row there is exactly one free position.
Next, repeat with the 2 which have to fit in the remaining places.
Now the problem is that we might not be able to actually complete the square. We may find there are some constraints which make it impossible to fill in the last digits. The problem is that checking a partially filled latin square is NP-complete.(wikipedia) This basically means pretty compute intensive and there no know short-cut algorithm. So I think the best you can do is generate squares and test if they work or not.
If you only want one particular square for each n then there might be simpler ways of generating them.
The link Ted Hopp gave in his comment Latin Squares. Simple Construction does provide a method for generating a square starting with the addition of integers mod n.
I might be wrong, but if you just look for printing a symmetric table - a special case of latin squares isomorphic to the symmetric difference operation table over a powerset({0,1,..,n}) mapped to a ring {0,1,2,..,2^n-1}.
One can also produce such a table, using XOR(i,j) where i and j are n*n table indexes.
For example:
def latin_powerset(n):
for i in range(n):
for j in range(n):
yield (i, j, i^j)
Printing tuples coming from previously defined special-case generator of symmetric latin squares declared above:
def print_latin_square(sq, n=None):
cells = [c for c in sq]
if n is None:
# find the length of the square side
n = 1; n2 = len(cells)
while n2 != n*n:
n += 1
rows = list()
for i in range(n):
rows.append(" ".join("{0}".format(cells[i*n + j][2]) for j in range(n)))
print("\n".join(rows))
square = latin_powerset(8)
print(print_latin_square(square))
outputs:
0 1 2 3 4 5 6 7
1 0 3 2 5 4 7 6
2 3 0 1 6 7 4 5
3 2 1 0 7 6 5 4
4 5 6 7 0 1 2 3
5 4 7 6 1 0 3 2
6 7 4 5 2 3 0 1
7 6 5 4 3 2 1 0
See also
This covers more generic cases of latin squares, rather than that super symmetrical case with the trivial code above:
https://www.cut-the-knot.org/arithmetic/latin2.shtml (also pointed in the comments above for symmetric latin square construction)
https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/matrices/latin.html

Partitioning a circular buffer while keeping order

I've got a circular buffer with positive natural values, e.g.
1 5
4 2
11 7
2 9
We're going to partition it into exactly two continuous parts, while keeping this order. These two parts in this example could be:
(4 1 5) and (2 7 9 2 11),
(7 9 2 11 4) and (1 5 2),
etc.
The idea is to keep order and take two continuous subsequences.
And the problem now is to partition it so that the sums of these subsequences are closes to each other, i.e. the difference between the sums must be closest to zero.
In this case, I believe the solution would be: (2 7 9 2) and (11 4 1 5) with sums, respectively, 20 and 21.
How to do this optimally?
Algorithm:
Calculate the total sum.
Let the current sum = 0.
Start off with 2 pointers at any point (both starting off at the same point).
Increase the second pointer, adding the number it passed, until the current sum is more than half of the total sum.
Increase the first pointer, subtracting the number it passed, until the current sum is less than half of the total sum.
Stop if either:
The first pointer is back where it started, or
The best sum is 0.5 or 0 from half the total sum (in which case the difference will be 1 or 0).
The difference can be 1 only if the total sum is odd, in which case the difference can never be 0. (Thanks Artur!)
Otherwise repeat from step 3.
Check all the current sums we got in this process and keep the one that's closest to half, along with indices of the partition that got that sum.
Running time:
The running time will be O(n), since we only ever increase the pointers and the first one only goes around once, and the second one can't go around more than twice.
Example:
Input:
1 5
4 2
11 7
2 9
Total sum = 41.
Half of sum = 20.5.
So, let's say we start off at 1. (I just put it on a straight line to make it easier to draw)
p1, p2
V
1 5 2 7 9 2 11 4
sum = 0
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 1
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 6
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 8
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 15
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 24
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 23
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 18
p1 p2
V V
1 5 2 7 9 2 11 4
sum = 20
Here the sum (20) is 0.5 from half the total sum (20.5), so we can stop.
The above corresponds to (11 4 1 5) (2 7 9 2), with a difference in sums of 1.

How to solve terrain map shortest path with dynamic programming?

Given a matrix of all positive integers, starting from the left most column 0th, find the minimum path to the right most column (n - 1)th. For example:
The minimum path is the path which contains on 1's.
At any given square m[i, j], we can move to 4 directions (left, right, up, down); of course except all corner cases at left most, right most row/column. For example, at [0, 0], we only can move right or down.
My solution is to build a graph of m x n vertices, then run Floyd-Warshall to compute all pair shortest path of any two vertices (u, v). Then run another nested for loop to check all the vertices of the 0th column with all vertices of the (n - 1)th column to find the minimum path.
However, my professor suggested another algorithm by using the following recurrence:
S[i, j, L] =
min(
S[i - 1, j, L - 1] + cost[i - 1, j],
S[i + 1, j, L - 1] + cost[i + 1, j],
S[i, j - 1, L - 1] + cost[i, j - 1],
S[i, j + 1, L - 1] + cost[i, j + 1]);
which I have no clue how it works! Since at any given square [i, j] we can move in 4 direction and this make it impossible to build a table based on previous pre-computed values.
Did I miss something here? I can't see how this recurrence work out. Any idea?
If you have S[i,j,0] = infinity, except for S[0,j,L] = 0, then it should work. Eventually all S[i,j,L]==S[i,j,L+1] and you can stop iterating. S[i,j,L] then has the cost of the shortest path from the first column to that cell.
This is how this recurrence would look in the upper-left corner for increasing values of L.
0 inf inf inf inf
0 inf inf inf inf
0 inf inf inf inf
0 1 inf inf inf inf
0 20 inf inf inf inf
0 21 inf inf inf inf
0 1 2 inf inf inf
0 2 30 inf inf inf
0 21 22 inf inf inf
0 1 2 3 inf inf
0 2 3 39 inf inf
0 12 22 23 inf inf
0 1 2 3 4 inf
0 2 3 4 47 inf
0 12 12 23 24 inf
0 1 2 3 4 5
0 2 3 4 5 48
0 12 12 12 24 25
0 1 2 3 4 5
0 2 3 4 5 6
0 12 12 12 6 25
0 1 2 3 4 5
0 2 3 4 5 6
0 12 12 7 6 7
0 1 2 3 4 5
0 2 3 4 5 6
0 12 8 7 6 7
0 1 2 3 4 5
0 2 3 4 5 6
0 9 8 7 6 7
No further changes will take place in the upper-left corner. You can see that it is slowly discovering the minimum cost to reach each cell.

Resources