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 \ 3Output: 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:Â
Â5 / \ 3 2 / \ / \ 1 4 1 2Output: 1 3 5 2 2
Explanation:Â Â
5,4 and 1 are at same verticle distance (i.e 0), count of set bit at 0th position = 2 and count of clear bit = 1. Therefore, 1th bit of the resultant node is set.
5,4 and 1 are at same verticle distance (i.e 0), count of set bit at 1st position = 0 and count of clear bit = 3. Therefore, 0th bit of the resultant node is set.Â
5,4 and 1 are at same verticle distance (i.e 0), count of set bit at 2nd position = 2 and count of clear bit = 1. Therefore, 1th bit of the resultant node is set.
Rest of the nodes are at distinct verticle distance.Input:Â
Â1 / \ 2 3 / \ / \ 11 3 4 10 / / \ \ \ 9 7 8 2 4Output: 9 Â 11 Â 2 Â 1 Â 2 Â 10 Â 4Â
Â
Â
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:
C++
// C++ program for the above approachÂ
#include <bits/stdc++.h>using namespace std;Â
// Structure of a node of the treeclass Node {public:Â Â Â Â int val;Â Â Â Â Node *left, *right;Â
    Node(int val)    {        this->val = val;        left = right = NULL;    }};Â
// Function to compress all the nodes on the same vertical// linevoid evalComp(vector<int>& arr){    // Stores node by compressing all nodes on the current    // vertical line    int ans = 0;Â
    // Check if i-th bit of current bit set or not    int getBit = 1;Â
    // Iterate over the range [0, 31]    for (int i = 0; i < 32; i++) {        // Stores count of set bits at i-th positions        int S = 0;        // Stores count of clear bits at i-th positions        int NS = 0;Â
        // Traverse the array        for (auto j : arr) {            // If i-th bit of current element is set            if (getBit & j)                S++; // Update SÂ
            else                NS++; // Update NS        }        // If count of set bits at i-th position is greater        // than count of clear bits        if (S > NS)            // Update ans            ans += pow(2, i);Â
        // Update getBit        getBit <<= 1;    }Â
    cout << ans << " ";}Â
// Function to traverse the tree and map all the nodes of// same vertical line to vertical distancevoid Trav(Node* root, int hd, map<int, vector<int> >& mp){Â Â Â Â if (!root)Â Â Â Â Â Â Â Â return;Â
    // Storing the values in the map    mp[hd].push_back(root->val);Â
    // Recursive calls on left and right subtree    Trav(root->left, hd - 1, mp);    Trav(root->right, hd + 1, mp);}Â
// Function to compress all the nodes on the same vertical// line with a single node that satisfies the conditionvoid compressTree(Node* root){    // Map all the nodes on the same vertical line    map<int, vector<int> > mp;Â
    Trav(root, 0, mp);Â
    // Getting the range of horizontal distances    int lower, upper;    for (auto i : mp) {        lower = min(lower, i.first);        upper = max(upper, i.first);    }Â
    for (int i = lower; i <= upper; i++)        evalComp(mp[i]);}Â
// Driver Codeint main(){Â Â Â Â Node* root = new Node(5);Â Â Â Â root->left = new Node(3);Â Â Â Â root->right = new Node(2);Â Â Â Â root->left->left = new Node(1);Â Â Â Â root->left->right = new Node(4);Â Â Â Â root->right->left = new Node(1);Â Â Â Â root->right->right = new Node(2);Â
    // Function Call    compressTree(root);Â
    return 0;}Â
// This code is contributed by Tapesh(tapeshdua420) |
Java
// Java program for the above approachimport java.util.*;Â
class GFG {    // Structure of a node of the tree    static class Node {        int val;        Node left, right;Â
        Node(int val)        {            this.val = val;            left = right = null;        }    }    // Driver Code    public static void main(String[] args)    {        Node root = new Node(5);        root.left = new Node(3);        root.right = new Node(2);        root.left.left = new Node(1);        root.left.right = new Node(4);        root.right.left = new Node(1);        root.right.right = new Node(2);Â
        compressTree(root);    }    // Function to compress all the nodes on the same    // vertical line    public static void evalComp(ArrayList<Integer> arr)    {        // Stores node by compressing all nodes on the        // currentvertical line        int ans = 0;        // Check if i-th bit of current bit set or not        int getBit = 1;        // Iterate over the range [0, 31]        for (int i = 0; i < 32; i++) {            // Stores count of set bits at i-th positions            int S = 0;            // Stores count of clear bits at i-th positions            int NS = 0;Â
            // Traverse the array            for (int j : arr) {                // If i-th bit of current element is set                if ((getBit & j) != 0)                    S++; // Update S                else                    NS++; // Update NS            }            // If count of set bits at i-th position is            // greater            // than count of clear bits            if (S > NS)                // Update ans                ans += Math.pow(2, i);            // Update getBit            getBit <<= 1;        }        System.out.print(ans + " ");    }    // Function to traverse the tree and map all the nodes    // of same vertical line to vertical distance    public static void    Trav(Node root, int hd,         HashMap<Integer, ArrayList<Integer> > mp)    {        if (root == null)            return;Â
        // Storing the values in the map        mp.putIfAbsent(hd, new ArrayList<>());        mp.get(hd).add(root.val);Â
        // Recursive calls on left and right subtree        Trav(root.left, hd - 1, mp);        Trav(root.right, hd + 1, mp);    }    // Function to compress all the nodes on the same    // vertical    // line with a single node that satisfies the condition    public static void compressTree(Node root)    {        // Map all the nodes on the same vertical line        HashMap<Integer, ArrayList<Integer> > mp            = new HashMap<>();Â
        Trav(root, 0, mp);Â
        // Getting the range of horizontal distances        int lower = Integer.MAX_VALUE, upper                                       = Integer.MIN_VALUE;        for (Map.Entry<Integer, ArrayList<Integer> > i :             mp.entrySet()) {            lower = Math.min(lower, i.getKey());            upper = Math.max(upper, i.getKey());        }        for (int i = lower; i <= upper; i++)            evalComp(mp.get(i));    }}Â
// This code is contributed by Tapesh(tapeshdua420) |
Python3
# Python3 program for the above approachÂ
# Structure of a node# of the treeclass 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 linedef 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 conditiondef 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 Codeif __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) |
C#
// C# program for the above approachusing System;using System.Collections.Generic;Â
// Structure of a node of the treeclass Node {Â Â Â Â public int val;Â Â Â Â public Node left;Â Â Â Â public Node right;Â
    public Node(int data)    {        val = data;        left = right = null;    }}Â
class Program {    // Driver Code    static void Main(string[] args)    {Â
        Node root = new Node(5);        root.left = new Node(3);        root.right = new Node(2);        root.left.left = new Node(1);        root.left.right = new Node(4);        root.right.left = new Node(1);        root.right.right = new Node(2);Â
        compressTree(root);    }    // Function to compress all the nodes on the same    // vertical line    public static void evalComp(List<int> arr)    {        // Stores node by compressing all nodes on the        // currentvertical line        int ans = 0;        // Check if i-th bit of current bit set or not        int getBit = 1;        // Iterate over the range [0, 31]        for (int i = 0; i < 32; i++) {            // Stores count of set bits at i-th positions            int S = 0;            // Stores count of clear bits at i-th positions            int NS = 0;Â
            // Traverse the array            foreach(int j in arr)            {                // If i-th bit of current element is set                if ((getBit & j) != 0)                    S++; // Update S                else                    NS++; // Update NS            }            // If count of set bits at i-th position is            // greater            // than count of clear bits            if (S > NS)                // Update ans                ans += (int)Math.Pow(2, i);            // Update getBit            getBit <<= 1;        }Â
        Console.Write(ans + " ");    }Â
    // Function to traverse the tree and map all the nodes    // of same vertical line to vertical distance    public static void Trav(Node root, int hd,                            Dictionary<int, List<int> > mp)    {        if (root == null)            return;Â
        // Storing the values in the map        if (mp.ContainsKey(hd) == false)            mp[hd] = new List<int>();        mp[hd].Add(root.val);Â
        // Recursive calls on left and right subtree        Trav(root.left, hd - 1, mp);        Trav(root.right, hd + 1, mp);    }       // Function to compress all the nodes on the same    // vertical    // line with a single node that satisfies the condition    public static void compressTree(Node root)    {        // Map all the nodes on the same vertical line        Dictionary<int, List<int> > mp            = new Dictionary<int, List<int> >();        Trav(root, 0, mp);Â
        // Getting the range of horizontal distances        int lower = Int32.MaxValue, upper = Int32.MinValue;        foreach(KeyValuePair<int, List<int> > i in mp)        {            lower = Math.Min(lower, i.Key);            upper = Math.Max(upper, i.Key);        }Â
        for (int i = lower; i <= upper; i++)            evalComp(mp[i]);    }}Â
// This code is contributed by Tapesh(tapeshdua420) |
Javascript
<script>// Javascript program for the above approachÂ
// Structure of a node// of the treeclass 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 linefunction 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 conditionfunction 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 CallcompressTree(root);Â
// This code is contributed by _saurabh_jaiswal.</script> |
1 3 5 2 2
Â
Time Complexity: O(N logN), where N is the number of nodes in the binary tree.
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
