Open In App

Find Nested List Weight Sum II

Last Updated : 09 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a nested list of integers nestedList. Each element is either an integer or a list whose elements may also be integers or other lists. The depth of an integer is the number of lists that it is inside of. For example, the nested list [1,[2,2],[[3],2],1] has each integer’s value set to its depth.

Let maxDepth be the maximum depth of any integer. The weight of an integer is maxDepth – (the depth of the integer) + 1.

Your task is to find the sum of each integer in nestedList multiplied by its weight.

Examples:

Input: nestedList = [[1, 1], 2, [1, 1]]
Output:  8
Explanation: Four 1’s with a weight of 1, one 2 with a weight of 2. 1*1 + 1*1 + 2*2 + 1*1 + 1*1 = 8

Input: nestedList = [1, [3, [5]]]
Output:  14
Explanation: One 1 at depth 3, one 3 at depth 2, and one 5 at depth 1; 1*3 + 3*2 + 5*1 = 14)

Algorithm: To solve the problem, follow the below idea:

We can solve this problem by recursively flattening the nested list while tracking each element’s depth and calculating the maximum depth encountered. Then, iterating through the flattened list, it computes the depth sum inverse for each element using the maximum depth and the element’s depth. Finally, it returns the sum of these depth sum inverses.

Step-by-step algorithm:

  • Initialize an empty list flats to store the flattened elements along with their depth.
  • Initialize max_depth to store the maximum depth encountered.
  • Define a function flatten that takes the nested list, current depth, flats list, and max_depth.
  • Iterate through each element of the nested list:
    • If the element is an integer, append it to flats with its corresponding depth.
    • If the element is a nested list, recursively call flatten with the nested list, incremented depth, flats, and max_depth.
    • Update max_depth to the maximum of current depth and max_depth.
  • Define a function depth_sum_inverse that takes the nested list and returns the depth sum inverse.
  • Call the flatten function with the nested list, initial depth 0, flats list, and max_depth.
  • Calculate the depth sum inverse by iterating through flats, summing the product of each element and (max_depth + 1 - depth).
  • Return the calculated depth sum inverse.

Below is the implementation of the algorithm:

C++
#include <iostream>
#include <memory>
#include <vector>

// Abstract base class representing a Nested Integer, which
// could be either an integer or a nested list of integers.
class NestedInteger {
public:
    virtual ~NestedInteger() {}
    // Returns true if this NestedInteger holds a single
    // integer, rather than a nested list.
    virtual bool isInteger() const = 0;
    // Returns the single integer that this NestedInteger
    // holds, if it holds a single integer.
    virtual int getInteger() const = 0;
    // Returns the nested list that this NestedInteger
    // holds, if it holds a nested list.
    virtual const std::vector<NestedInteger*>&
    getList() const = 0;
};

// Concrete implementation of NestedInteger to hold a single
// integer.
class Integer : public NestedInteger {
    int value;

public:
    Integer(int value)
        : value(value)
    {
    }
    bool isInteger() const override { return true; }
    int getInteger() const override { return value; }
    const std::vector<NestedInteger*>&
    getList() const override
    {
        throw std::runtime_error("This is not a list");
    }
};

// Concrete implementation of NestedInteger to hold a list
// of NestedInteger objects.
class List : public NestedInteger {
    std::vector<NestedInteger*> list;

public:
    List(const std::vector<NestedInteger*>& list)
        : list(list)
    {
    }
    ~List()
    {
        for (auto item : list) {
            delete item; // Clean up memory to prevent leaks
        }
    }
    bool isInteger() const override { return false; }
    int getInteger() const override
    {
        throw std::runtime_error("This is not an integer");
    }
    const std::vector<NestedInteger*>&
    getList() const override
    {
        return list;
    }
};

// Flattens a nested list into a simple list of integers
// with their associated depths.
void flatten(const NestedInteger& ni, int depth,
             std::vector<std::pair<int, int> >& flatList,
             int& maxDepth)
{
    if (ni.isInteger()) {
        flatList.push_back({ ni.getInteger(), depth });
        maxDepth = std::max(maxDepth, depth);
    }
    else {
        for (auto item : ni.getList()) {
            flatten(*item, depth + 1, flatList, maxDepth);
        }
    }
}

// Calculates the inverse depth sum of a nested list.
int depthSumInverse(
    const std::vector<NestedInteger*>& nestedList)
{
    std::vector<std::pair<int, int> > flatList;
    int maxDepth = 0;
    for (auto item : nestedList) {
        flatten(*item, 0, flatList, maxDepth);
    }

    int sum = 0;
    for (const auto& p : flatList) {
        sum += p.first
               * (maxDepth + 1
                  - p.second); // Weight the value by its
                               // inverse depth
    }
    return sum;
}

int main()
{
    // Create and test nested lists with different
    // structures to validate the functionality.
    std::vector<NestedInteger*> nestedList1
        = { new List({ new Integer(1), new Integer(1) }),
            new Integer(2),
            new List({ new Integer(1), new Integer(1) }) };

    std::vector<NestedInteger*> nestedList2
        = { new Integer(1),
            new List({ new Integer(3),
                       new List({ new Integer(5) }) }) };

    std::cout << depthSumInverse(nestedList1) << std::endl;
    std::cout << depthSumInverse(nestedList2) << std::endl;

    // Clean up the allocated NestedIntegers to avoid memory
    // leaks.
    for (auto item : nestedList1) {
        delete item;
    }
    for (auto item : nestedList2) {
        delete item;
    }

    return 0;
}
Java
import java.util.*;

public class Main {
    // Class to store element and its depth
    static class Node {
        int val, depth;
        Node(int val, int depth)
        {
            this.val = val;
            this.depth = depth;
        }
    }

    // Function to flatten the nested list and calculate
    // maximum depth.
    static void flatten(List<Object> nestedList, int depth,
                        List<Node> flatList, int[] maxDepth)
    {
        for (Object obj : nestedList) {
            if (obj instanceof Integer) {
                flatList.add(new Node((Integer)obj, depth));
                maxDepth[0] = Math.max(maxDepth[0], depth);
            }
            else {
                flatten((List<Object>)obj, depth + 1,
                        flatList, maxDepth);
            }
        }
    }

    // Function to calculate the depth sum inverse of a
    // nested list.
    static int depthSumInverse(List<Object> nestedList)
    {
        List<Node> flatList = new ArrayList<>();
        int[] maxDepth = new int[1];
        flatten(nestedList, 0, flatList, maxDepth);

        int sum = 0;
        for (Node node : flatList) {
            sum += node.val
                   * (maxDepth[0] + 1 - node.depth);
        }
        return sum;
    }

    public static void main(String[] args)
    {
        List<Object> nestedList = Arrays.asList(
            Arrays.asList(1, 1), 2, Arrays.asList(1, 1));
        System.out.println(depthSumInverse(nestedList));

        List<Object> nestedList2 = Arrays.asList(
            1, Arrays.asList(3, Arrays.asList(5)));
        System.out.println(depthSumInverse(nestedList2));
    }
}
Python
# Function to flatten the nested list and calculate maximum depth.


def flatten(nlst, dist, flats, maxd):

    for node in nlst:
        # If the node is an integer, add it to flats along with its distance.
        if isinstance(node, int):
            flats.append((node, dist))
        else:
            # If the node is a sublist, recursively flatten it with increased distance.
            flatten(node, dist + 1, flats, maxd)
        # Update maxd to keep track of the maximum distance encountered.
        maxd[0] = max(maxd[0], dist)

#  Function to calculate the depth sum inverse of a nested list.


def depth_sum_inverse(nested_list):
    flats = []  # List to store flattened elements along with their distances
    maxd = [0]  # List to store the maximum distance encountered
    flatten(nested_list, 0, flats, maxd)

    summ = 0
    # Calculate the depth sum inverse using the flattened elements and maximum distance
    for v, d in flats:
        summ += v * (maxd[0] + 1 - d)
    return summ


# Example usage
nested_list = [[1, 1], 2, [1, 1]]
print(depth_sum_inverse(nested_list))

nestedList2 = [1, [3, [5]]]
print(depth_sum_inverse(nestedList2))
JavaScript
// Class to store element and its depth
class Node {
    constructor(val, depth) {
        this.val = val;
        this.depth = depth;
    }
}

// Function to flatten the nested list and calculate maximum depth
function flatten(nestedList, depth, flatList, maxDepth) {
    for (let obj of nestedList) {
        if (typeof obj === 'number') {
            flatList.push(new Node(obj, depth));
            maxDepth[0] = Math.max(maxDepth[0], depth);
        } else {
            flatten(obj, depth + 1, flatList, maxDepth);
        }
    }
}

// Function to calculate the depth sum inverse of a nested list
function depthSumInverse(nestedList) {
    let flatList = [];
    let maxDepth = [0];
    flatten(nestedList, 0, flatList, maxDepth);

    let sum = 0;
    for (let node of flatList) {
        sum += node.val * (maxDepth[0] + 1 - node.depth);
    }
    return sum;
}

// Main function
function main() {
    let nestedList1 = [[1, 1], 2, [1, 1]];
    console.log(depthSumInverse(nestedList1));

    let nestedList2 = [1, [3, [5]]];
    console.log(depthSumInverse(nestedList2));
}

main();

Output
8
14

Time Complexity : O(N), where is the total number of elements in the nested list.
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads