Open In App

Difference of Max and Min Subtree Sums in Tree Nodes

Last Updated : 13 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a tree containing N nodes in the form of an array P where Pi represents the parent of the i-th node and P1 = -1 as the tree is rooted at node 1. Also given an array vals which consists of the value of the ith node from 1 to N. For each node in the tree find the difference between the maximum and minimum subtree sum.

Examples:

Input: N = 6, par[] = [-1, 1, 1, 2, 2, 4], vals[] = [2, 1, 4, 6, 2, 5]
Output: 10 9 0 0 0 0
Explanation:

  • For node 1:- the sum of subtrees are 14 and 4 so the difference between maximum and minimum is 10.
  • For node 2:- the difference is 9.
  • For nodes with a single child the max and min are the same so the difference is 0.

Nodes with 0 child (leaf nodes) have no subtrees hence their difference is 0.

Input: N = 4, par[] = [-1, 1, 1, 1], vals[] = [1, 2, 3, 4]
Output: 2 0 0 0
Explanation: For node 1 the sum of subtrees are 2, 3 and 4 so the difference between the maximum and minimum is 2.

Approach: This can be solved with the following idea:

Iterating over each node, check with maximum and minimum node value and update the mx and mn value and traverse upto leaf node. Return the difference in ans array.

Below are the steps involved:

  • Create a adjancy matrix adj.
  • Call the func fun:
    • Iterate over each node:
      • Update maximum and minimum value for each node.
      • Add the sum in total and return the value accordingly.
    • Update the difference between mx – mn in ans array.
  • Return ans.

Below is the implementation of the code:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Function to find minimum
// and maximum subtree
long long fun(int i, vector<long long>& ans,
              vector<int> adj[], vector<int>& val)
{
 
    long long mx = -1e18 + 0, mn = 1e18 + 0;
    long long total = 0;
 
    // Iterate in adjancy matrix
    for (auto it : adj[i]) {
 
        long long find = 0;
        find = fun(it, ans, adj, val);
 
        // Update the value
        mx = max(mx, find);
        mn = min(mn, find);
 
        total += find;
    }
 
    // Update the value in ans by their difference
    if (mx != -1e18 + 0) {
        ans[i - 1] = (mx - mn);
    }
 
    // Return the value.
    return total + val[i - 1];
}
 
// Function to find difference between maximum and minimum
// subtree
vector<long long> differenceTree(int n, vector<int>& par,
                                 vector<int>& vals)
{
 
    // Create a adjancy matrix
    vector<int> adj[n + 1];
 
    // Iterate in par array
    for (int i = 1; i < n; i++) {
        adj[par[i]].push_back(i + 1);
    }
 
    vector<long long> ans(n, 0);
 
    // Function to find minimum
    // and maximum subtree
    // Starting from root 1
    fun(1, ans, adj, vals);
 
    return ans;
}
 
// Driver code
int main()
{
 
    int N = 6;
    vector<int> pals = { -1, 1, 1, 2, 2, 4 };
    vector<int> vals = { 2, 1, 4, 6, 2, 5 };
 
    // Function call
    vector<long long> ans = differenceTree(N, pals, vals);
    for (auto a : ans) {
        cout << a << " ";
    }
    return 0;
}


Java




import java.util.*;
 
class DifferenceTree {
    static long fun(int i, List<Long> ans, List<Integer>[] adj, List<Integer> val) {
        long mx = Long.MIN_VALUE, mn = Long.MAX_VALUE;
        long total = 0;
 
        for (int it : adj[i]) {
            long find = fun(it, ans, adj, val);
 
            mx = Math.max(mx, find);
            mn = Math.min(mn, find);
 
            total += find;
        }
 
        if (mx != Long.MIN_VALUE) {
            ans.set(i - 1, mx - mn);
        }
 
        return total + val.get(i - 1);
    }
 
    static List<Long> differenceTree(int n, List<Integer> par, List<Integer> vals) {
        List<Integer>[] adj = new ArrayList[n + 1];
 
        for (int i = 0; i <= n; i++) {
            adj[i] = new ArrayList<>();
        }
 
        for (int i = 1; i < n; i++) {
            adj[par.get(i)].add(i + 1);
        }
 
        List<Long> ans = new ArrayList<>(Collections.nCopies(n, 0L));
        fun(1, ans, adj, vals);
 
        return ans;
    }
 
    public static void main(String[] args) {
        int N = 6;
        List<Integer> pals = Arrays.asList(-1, 1, 1, 2, 2, 4);
        List<Integer> vals = Arrays.asList(2, 1, 4, 6, 2, 5);
 
        List<Long> ans = differenceTree(N, pals, vals);
        for (long a : ans) {
            System.out.print(a + " ");
        }
    }
}


Python3




def difference_tree(n, par, vals):
    # Create an adjacency list
    adj = [[] for _ in range(n + 1)]
 
    # Iterate in par array
    for i in range(1, n):
        adj[par[i]].append(i + 1)
 
    ans = [0] * n
 
    # Function to find minimum and maximum subtree, starting from root 1
    def fun(i):
        nonlocal ans
        mx = float('-inf')
        mn = float('inf')
        total = 0
 
        # Iterate in adjacency list
        for it in adj[i]:
            find = fun(it)
 
            # Update the value
            mx = max(mx, find)
            mn = min(mn, find)
 
            total += find
 
        # Update the value in ans by their difference
        if mx != float('-inf'):
            ans[i - 1] = (mx - mn)
 
        # Return the value
        return total + vals[i - 1]
 
    # Function call starting from root 1
    fun(1)
 
    return ans
 
# Driver code
if __name__ == "__main__":
    N = 6
    pals = [-1, 1, 1, 2, 2, 4]
    vals = [2, 1, 4, 6, 2, 5]
 
    # Function call
    ans = difference_tree(N, pals, vals)
     
    # Print the result
    for a in ans:
        print(a, end=" ")
# this code is contributed by utkarsh


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // Function to find minimum and maximum subtree
    static long Fun(int i, List<long> ans, List<List<int>> adj, List<int> val)
    {
        long mx = long.MinValue, mn = long.MaxValue;
        long total = 0;
 
        // Iterate in adjacency list
        foreach (int it in adj[i])
        {
            long find = Fun(it, ans, adj, val);
 
            // Update the value
            mx = Math.Max(mx, find);
            mn = Math.Min(mn, find);
 
            total += find;
        }
 
        // Update the value in ans by their difference
        if (mx != long.MinValue)
        {
            ans[i - 1] = (mx - mn);
        }
 
        // Return the value.
        return total + val[i - 1];
    }
 
    // Function to find difference between maximum and minimum subtree
    static List<long> DifferenceTree(int n, List<int> par, List<int> vals)
    {
        // Create an adjacency list
        List<List<int>> adj = new List<List<int>>();
        for (int i = 0; i <= n; i++)
        {
            adj.Add(new List<int>());
        }
 
        // Iterate in par array
        for (int i = 1; i < n; i++)
        {
            adj[par[i]].Add(i + 1);
        }
 
        List<long> ans = new List<long>(new long[n]);
 
        // Function to find minimum and maximum subtree
        // Starting from root 1
        Fun(1, ans, adj, vals);
 
        return ans;
    }
 
    // Driver code
    static void Main(string[] args)
    {
        int N = 6;
        List<int> pals = new List<int> { -1, 1, 1, 2, 2, 4 };
        List<int> vals = new List<int> { 2, 1, 4, 6, 2, 5 };
 
        // Function call
        List<long> ans = DifferenceTree(N, pals, vals);
        foreach (long a in ans)
        {
            Console.Write(a + " ");
        }
    }
}
//This code is contributed by utkarsh


Javascript




// Function to find minimum and maximum subtree
function fun(i, ans, adj, val) {
    let mx = -1e18 + 0;
    let mn = 1e18 + 0;
    let total = 0;
 
    // Iterate over the adjacency list
    for (let it of adj[i]) {
        let find = fun(it, ans, adj, val);
 
        // Update the value
        mx = Math.max(mx, find);
        mn = Math.min(mn, find);
 
        total += find;
    }
 
    // Update the value in ans by their difference
    if (mx != -1e18 + 0) {
        ans[i - 1] = mx - mn;
    }
 
    // Return the value
    return total + val[i - 1];
}
 
// Function to find difference between maximum and minimum subtree
function differenceTree(n, par, vals) {
    let adj = new Array(n + 1).fill().map(() => []);
 
    // Iterate over the par array
    for (let i = 1; i < n; i++) {
        adj[par[i]].push(i + 1);
    }
 
    let ans = new Array(n).fill(0);
 
    // Call the function to find minimum and maximum subtree starting from root 1
    fun(1, ans, adj, vals);
 
    return ans;
}
 
// Driver code
function main() {
    let N = 6;
    let pals = [-1, 1, 1, 2, 2, 4];
    let vals = [2, 1, 4, 6, 2, 5];
 
    // Function call
    let ans = differenceTree(N, pals, vals);
    for (let a of ans) {
        console.log(a + " ");
    }
}
 
// Run the main function
main();
//This code is contributed by utkarsh


Output

10 9 0 0 0 0 


Output

10 9 0 0 0 0 




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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads