Given a tree with N vertices from 0 to N-1 (0th node is root) and val[] where val[i] denotes the value of the ith vertex. The task is to find the array of integers ans[] of length N, where ans[i] denotes the mode value of all its ancestors’ values including ith vertex.
Note: Mode is the value that has the highest frequency in a given set of values(if there is more than one value having the highest frequency return the largest among them).
Examples:
Input: Below is the given Tree:
val[] = [5, 2, 3, 2, 5, 1, 3, 5, 1]
Output: 5 5 5 2 5 5 3 5 5
Explanation:
node 0: {5}, mode = 5
node 1: {5, 2}, mode = 5
node 2: {5, 3}, mode = 5
node 3: {5, 2, 2}, mode = 2
node 4: {5, 2, 5}, mode = 5
node 5: {5, 2, 1}, mode = 5
node 6: {5, 3, 3}, mode = 3
node 7: {5, 3, 5}, mode = 5
node 8: {5, 3, 1}, mode = 5Input: Below is the given Tree:
val[] = [1, 3, 2, 1]
Output: 1 3 2 1
Approach: The problem can be solved based on the following idea:
Use DFS traversal from root to all nodes in top-down manner and use a map to store the frequency of all the ancestors for a node.
Follow the steps mentioned below to implement the idea
- Use a top-down DFS to traverse from the root to all the nodes and use a map freq to store the frequency of all ancestors.
- Create a set pair s to store values and frequency of values of all ancestors in the path from the root to the current node.
-
Whenever entering a node, before calling DFS on its children, increment the value of that node in freq[] and accordingly update the set s.
- Whenever we exit the node, decrement the value of that node in freq[] and accordingly update the set s.
- This ensures that the set will contain the frequency of each value of all ancestors (node itself) of the current node.
- Use a map ans[] to store the required answer for each node by taking the last element of the set(highest freq value) and use that to print the final solution.
Below is the implementation of the above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Map to store final ans for each node unordered_map< int , int > ans;
// Map to store frequency of values unordered_map< int , int > freq;
// Set to store freq of value and value itself set<pair< int , int > > s;
// Function to add an edge // between nodes u and v void addEdge(vector< int > adj[], int u, int v)
{ adj[u].push_back(v);
adj[v].push_back(u);
} // Change the values of freq and set s void helper( int v, int flag)
{ if (s.find({ freq[v], v }) != s.end())
s.erase(s.find({ freq[v], v }));
freq[v] += flag;
s.insert({ freq[v], v });
} // Mode of Ancestor void ModeOfAncestors(vector< int > adj[], int node,
vector< int >& vis, vector< int >& val)
{ int v = val[node];
// Increment the freq of value v by one
helper(v, 1);
ans[node] = (*(--s.end())).second;
vis[node] = 1;
for ( auto child : adj[node]) {
if (vis[child] == 0)
ModeOfAncestors(adj, child, vis, val);
}
// Decrement the freq of value v by one
helper(v, -1);
} // Driver Code int main()
{ // Number of nodes in a tree
int N = 9;
// Initialize tree
vector< int > adj[N];
// Tree Formation
addEdge(adj, 0, 1);
addEdge(adj, 0, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 1, 5);
addEdge(adj, 2, 6);
addEdge(adj, 2, 7);
addEdge(adj, 2, 8);
// Values of nodes of tree
vector< int > val = { 5, 2, 3, 2, 5, 1, 3, 5, 1 };
vector< int > vis(N, 0);
// Function call
ModeOfAncestors(adj, 0, vis, val);
for ( int i = 0; i < N; i++)
cout << ans[i] << " " ;
cout << endl;
return 0;
} |
import java.util.*;
public class ModeOfAncestors {
// Map to store the final answer for each node
private static Map<Integer, Integer> ans = new HashMap<>();
// Map to store the frequency of values
private static Map<Integer, Integer> freq = new HashMap<>();
// Set to store frequency of value and value itself
private static TreeSet<Pair> s = new TreeSet<>(Comparator.comparing(Pair::getFrequency).thenComparing(Pair::getValue));
static class Pair {
int value;
int frequency;
public Pair( int value, int frequency) {
this .value = value;
this .frequency = frequency;
}
public int getValue() {
return value;
}
public int getFrequency() {
return frequency;
}
}
// Function to add an edge between nodes u and v
private static void addEdge(List<Integer>[] adj, int u, int v) {
adj[u].add(v);
adj[v].add(u);
}
// Change the values of freq and set s
private static void helper( int v, int flag) {
if (!freq.containsKey(v)) {
freq.put(v, 0 );
}
Pair pair = new Pair(v, freq.get(v));
s.remove(pair);
freq.put(v, freq.get(v) + flag);
s.add( new Pair(v, freq.get(v)));
}
// Mode of Ancestor
private static void modeOfAncestors(List<Integer>[] adj, int node, int [] vis, List<Integer> val) {
int v = val.get(node);
// Increment the frequency of value v by one
helper(v, 1 );
ans.put(node, s.last().getValue());
vis[node] = 1 ;
for ( int child : adj[node]) {
if (vis[child] == 0 ) {
modeOfAncestors(adj, child, vis, val);
}
}
// Decrement the frequency of value v by one
helper(v, - 1 );
}
public static void main(String[] args) {
// Number of nodes in a tree
int N = 9 ;
// Initialize the tree
List<Integer>[] adj = new ArrayList[N];
for ( int i = 0 ; i < N; i++) {
adj[i] = new ArrayList<>();
}
// Tree Formation
addEdge(adj, 0 , 1 );
addEdge(adj, 0 , 2 );
addEdge(adj, 1 , 3 );
addEdge(adj, 1 , 4 );
addEdge(adj, 1 , 5 );
addEdge(adj, 2 , 6 );
addEdge(adj, 2 , 7 );
addEdge(adj, 2 , 8 );
// Values of nodes of the tree
List<Integer> val = Arrays.asList( 5 , 2 , 3 , 2 , 5 , 1 , 3 , 5 , 1 );
int [] vis = new int [N];
// Function call
modeOfAncestors(adj, 0 , vis, val);
for ( int i = 0 ; i < N; i++) {
System.out.print(ans.get(i) + " " );
}
System.out.println();
}
} |
#Python3 code for the above approach # Map to store final ans for each node ans = {}
# Map to store frequency of values freq = {}
# Set to store freq of value and value itself s = set ()
# Function to add an edge between nodes u and v def add_edge(adj, u, v):
adj[u].append(v)
adj[v].append(u)
# Change the values of freq and set s def helper(v, flag):
if (freq[v], v) in s:
s.remove((freq[v], v))
freq[v] + = flag
s.add((freq[v], v))
# Mode of Ancestor def mode_of_ancestors(adj, node, vis, val):
v = val[node]
# Increment the freq of value v by one
helper(v, 1 )
ans[node] = max (freq, key = freq.get)
vis[node] = 1
for child in adj[node]:
if vis[child] = = 0 :
mode_of_ancestors(adj, child, vis, val)
# Decrement the freq of value v by one
helper(v, - 1 )
# Number of nodes in a tree N = 9
# Initialize tree adj = [[] for _ in range (N)]
# Tree Formation add_edge(adj, 0 , 1 )
add_edge(adj, 0 , 2 )
add_edge(adj, 1 , 3 )
add_edge(adj, 1 , 4 )
add_edge(adj, 1 , 5 )
add_edge(adj, 2 , 6 )
add_edge(adj, 2 , 7 )
add_edge(adj, 2 , 8 )
# Values of nodes of tree val = [ 5 , 2 , 3 , 2 , 5 , 1 , 3 , 5 , 1 ]
vis = [ 0 ] * N
for i, v in enumerate (val):
freq[v] = 0
# Function call mode_of_ancestors(adj, 0 , vis, val)
for i in range (N):
print (ans[i], end = " " )
print ()
#This code is contributed by Potta Lokesh |
// C# code to implement the approach using System;
using System.Collections.Generic;
public class Program {
// Map to store final ans for each node
static Dictionary< int , int > ans
= new Dictionary< int , int >();
// Map to store frequency of values
static Dictionary< int , int > freq
= new Dictionary< int , int >();
// Set to store freq of value and value itself
static SortedSet<Tuple< int , int > > s
= new SortedSet<Tuple< int , int > >();
// Function to add an edge
// between nodes u and v
static void addEdge(List< int >[] adj, int u, int v)
{
adj[u].Add(v);
adj[v].Add(u);
}
// Change the values of freq and set s
static void helper( int v, int flag)
{
if (freq.ContainsKey(v)
&& s.Contains(Tuple.Create(freq[v], v)))
s.Remove(Tuple.Create(freq[v], v));
freq[v]
= freq.ContainsKey(v) ? freq[v] + flag : flag;
s.Add(Tuple.Create(freq[v], v));
}
// Mode of Ancestor
static void ModeOfAncestors(List< int >[] adj, int node,
List< int > vis,
List< int > val)
{
int v = val[node];
// Increment the freq of value v by one
helper(v, 1);
ans[node] = s.Max.Item2;
vis[node] = 1;
foreach ( int child in adj[node])
{
if (vis[child] == 0)
ModeOfAncestors(adj, child, vis, val);
}
// Decrement the freq of value v by one
helper(v, -1);
}
// Driver Code
static void Main( string [] args)
{
// Number of nodes in a tree
int N = 9;
// Initialize tree
List< int >[] adj = new List< int >[ N ];
for ( int i = 0; i < N; i++)
adj[i] = new List< int >();
// Tree Formation
addEdge(adj, 0, 1);
addEdge(adj, 0, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 1, 5);
addEdge(adj, 2, 6);
addEdge(adj, 2, 7);
addEdge(adj, 2, 8);
// Values of nodes of tree
List< int > val
= new List< int >{ 5, 2, 3, 2, 5, 1, 3, 5, 1 };
List< int > vis = new List< int >( new int [N]);
// Function call
ModeOfAncestors(adj, 0, vis, val);
for ( int i = 0; i < N; i++)
Console.Write(ans[i] + " " );
Console.WriteLine();
}
} |
// // JavaScript code to implement the approach // Map to store final ans for each node let ans = {}; // Map to store frequency of values let freq = {}; // Set to store freq of value and value itself let s = new Set();
// Function to add an edge between nodes u and v function addEdge(adj, u, v) {
adj[u].push(v);
adj[v].push(u);
} // Change the values of freq and set s function helper(v, flag) {
if (s.has(`${freq[v]},${v}`)) {
s. delete (`${freq[v]},${v}`);
}
freq[v] += flag;
s.add(`${freq[v]},${v}`);
} // Mode of Ancestor function ModeOfAncestors(adj, node, vis, val) {
let v = val[node];
// Increment the freq of value v by one
helper(v, 1);
ans[node] = Object.entries(freq).reduce((a, e) => (freq[a[0]] > freq[e[0]] ? a : e), [v, 0])[0];
vis[node] = 1;
for (let child of adj[node]) {
if (vis[child] === 0) {
ModeOfAncestors(adj, child, vis, val);
}
}
// Decrement the freq of value v by one
helper(v, -1);
} // Driver Code // Number of nodes in a tree const N = 9; // Initialize tree let adj = new Array(N);
for (let i = 0; i < N; i++) {
adj[i] = [];
} // Tree Formation addEdge(adj, 0, 1); addEdge(adj, 0, 2); addEdge(adj, 1, 3); addEdge(adj, 1, 4); addEdge(adj, 1, 5); addEdge(adj, 2, 6); addEdge(adj, 2, 7); addEdge(adj, 2, 8); // Values of nodes of tree let val = [5, 2, 3, 2, 5, 1, 3, 5, 1]; let vis = new Array(N).fill(0);
for (let i = 0; i < val.length; i++) {
freq[val[i]] = 0;
} // Function call ModeOfAncestors(adj, 0, vis, val); // Output result console.log(Object.values(ans).join( " " ));
|
5 5 5 2 5 5 3 5 5
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)
Related Articles: