Open In App

Find most frequent value of ancestors for each Node of given Tree

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:



Example 1

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 = 5

Input: Below is the given Tree:

Example 2

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

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(" "));

Output
5 5 5 2 5 5 3 5 5 

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

Related Articles:


Article Tags :