Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Compress a Binary Tree from top to bottom with overlapping condition

  • Last Updated : 06 Aug, 2021

Given a binary tree, the task is to compress all the nodes on the same vertical line into a single node such that if the count of set bits of all the nodes on a vertical line at any position is greater than the count of clear bits at that position, then the bit of the single node at that position is set.

Examples:

Input: 
 

     1
      \
       2
      /
     1
      \
       3

Output: 1 2 
Explanation: 
1 and 1 are at same vertical distance, count of set bit at 0th position = 2 and count of clear bit = 0. Therefore, 0th bit of the resultant node is set. 
2 and 3 are at same vertical distance, count of set bit at 0th pos = 1 and count of clear bit = 1. Therefore, 0 bit is set of resultant node is not set. 
2 and 3 are at same vertical distance, count of set bit at 1st pos = 2 and count of clear bit = 0. Therefore, 1st bit of resultant node is set. 
 

 

Input: 
 

       1
     /   \
    3     2
   / \   /  \
  1   4 1    2

Output: 1 3 5 2 2 
 

 

Approach: The idea is to traverse the tree and to keep the track of the horizontal distance from the root node for each visited node. Below are the steps:

  • A map can be used to store the horizontal distance from the root node as the key and the values of the nodes as values.
  • After storing the values in the map check the number of set and non-set bits for each position and calculate the values accordingly.

Below is the implementation of the above approach:

Python3




# Python3 program for the above approach
 
# Structure of a node
# of th tree
class TreeNode:
    def __init__(self, val ='', left = None, right = None):
        self.val = val
        self.left = left
        self.right = right
         
         
# Function to compress all the nodes
# on the same vertical line
def evalComp(arr):
     
     
    # Stores node by compressing all
    # nodes on the current vertical line
    ans = 0
     
    # Check if i-th bit of current bit
    # set or not
    getBit = 1
     
    # Iterate over the range [0, 31]
    for i in range(32):
         
        # Stores count of set bits
        # at i-th positions
        S = 0
         
         
        # Stores count of clear bits
        # at i-th positions
        NS = 0
 
         
        # Traverse the array
        for j in arr:
           
            # If i-th bit of current element
            # is set
            if getBit & j:
                 
                 
                # Update S
                S += 1
            else:
                 
                # Update NS
                NS += 1
                 
        # If count of set bits at i-th position
        # is greater than count of clear bits
        if S > NS:
             
            # Update ans
            ans += 2**i
             
        # Update getBit   
        getBit <<= 1
         
         
    print(ans, end = " ")
 
 
# Function to compress all the nodes on
# the same vertical line with a single node
# that satisfies the condition
def compressTree(root):
     
     
    # Map all the nodes on the same vertical line
    mp = {}
 
 
    # Function to traverse the tree and map
    # all the nodes of same vertical line
    # to vertical distance
    def Trav(root, hd):
        if not root:
            return
 
 
        # Storing the values in the map
        if hd not in mp:
            mp[hd] = [root.val]
        else:
            mp[hd].append(root.val)
 
 
        # Recursive calls on left and right subtree
        Trav(root.left, hd-1)
        Trav(root.right, hd + 1)
 
    Trav(root, 0)
 
 
    # Getting the range of
    # horizontal distances
    lower = min(mp.keys())
    upper = max(mp.keys())
 
 
    for i in range(lower, upper + 1):
        evalComp(mp[i])
 
# Driver Code
if __name__ == '__main__':
     
    root = TreeNode(5)
    root.left = TreeNode(3)
    root.right = TreeNode(2)
    root.left.left = TreeNode(1)
    root.left.right = TreeNode(4)
    root.right.left = TreeNode(1)
    root.right.right = TreeNode(2)
 
    # Function Call
    compressTree(root)


Javascript




<script>
// Javascript program for the above approach
 
// Structure of a node
// of th tree
class TreeNode {
  constructor(val = "", left = null, right = null) {
    this.val = val;
    this.left = left;
    this.right = right;
  }
}
 
// Function to compress all the nodes
// on the same vertical line
function evalComp(arr) {
  // Stores node by compressing all
  // nodes on the current vertical line
  let ans = 0;
 
  // Check if i-th bit of current bit
  // set or not
  let getBit = 1;
 
  // Iterate over the range [0, 31]
  for (let i = 0; i < 32; i++) {
    // Stores count of set bits
    // at i-th positions
    let S = 0;
 
    // Stores count of clear bits
    // at i-th positions
    let NS = 0;
 
    // Traverse the array
    for (j of arr) {
      // If i-th bit of current element
      // is set
      if (getBit & j)
        // Update S
        S += 1;
      // Update NS
      else NS += 1;
    }
 
    // If count of set bits at i-th position
    // is greater than count of clear bits
    if (S > NS)
      // Update ans
      ans += 2 ** i;
 
    // Update getBit
    getBit <<= 1;
  }
 
  document.write(ans + " ");
}
 
// Function to compress all the nodes on
// the same vertical line with a single node
// that satisfies the condition
function compressTree(root) {
  // Map all the nodes on the same vertical line
  let mp = new Map();
 
  // Function to traverse the tree and map
  // all the nodes of same vertical line
  // to vertical distance
  function Trav(root, hd) {
    if (!root) return;
 
    // Storing the values in the map
    if (!mp.has(hd)) mp.set(hd, [root.val]);
    else {
      let temp = mp.get(hd);
      temp.push(root.val);
      mp.set(hd, temp);
    }
 
    // Recursive calls on left and right subtree
    Trav(root.left, hd - 1);
    Trav(root.right, hd + 1);
  }
 
  Trav(root, 0);
 
  // Getting the range of
  // horizontal distances
  let lower = [...mp.keys()].sort((a, b) => a - b)[0];
  let upper = [...mp.keys()].sort((a, b) => b - a)[0];
 
  for (let i = lower; i <= upper; i++) evalComp(mp.get(i));
}
 
// Driver Code
 
let root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(2);
root.left.left = new TreeNode(1);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(1);
root.right.right = new TreeNode(2);
 
// Function Call
compressTree(root);
 
// This code is contributed by _saurabh_jaiswal.
</script>


Output: 

1 3 5 2 2

 

Time Complexity: O(N)
Auxiliary Space: O(N)


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!