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++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Structure of a node of the tree class 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 // line void 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 distance void 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 condition void 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 Code int 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 program for the above approach import 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 program for the above approach # Structure of a node # of the 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)
|
// C# program for the above approach using System;
using System.Collections.Generic;
// Structure of a node of the tree class 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) |
<script> // Javascript program for the above approach // Structure of a node // of the 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> |
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)