package com.freetymekiyan.algorithms.level.medium; import com.freetymekiyan.algorithms.utils.Utils.NestedInteger; import java.util.ArrayList; import java.util.List; /** * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. * <p> * Each element is either an integer, or a list -- whose elements may also be integers or other lists. * <p> * Different from the previous question where weight is increasing from root to leaf, now the weight is defined from * bottom up. i.e., the leaf level integers have weight 1, and the root level integers have the largest weight. * <p> * Example 1: * Given the list [[1,1],2,[1,1]], return 8. (four 1's at depth 1, one 2 at depth 2) * <p> * Example 2: * Given the list [1,[4,[6]]], return 17. (one 1 at depth 3, one 4 at depth 2, and one 6 at depth 1; 1*3 + 4*2 + 6*1 = * 17) * <p> * Company Tags: LinkedIn * Tags: Depth-first Search * Similar Problems: (E) Nested List Weight Sum */ public class NestedListWeightSum2 { /** * DFS. * Instead of level, pass the integer sum of this level to the next level. * Recurrence Relation: * sum = this level's integers' sum + all previous levels integers' sum + all following levels integers' sum. * Base case: * If list is empty, return 0. */ public int depthSumInverse(List<NestedInteger> nestedList) { return dfs(nestedList, 0); } /** * DFS. * Create next level's list. * For each NestedInteger ni in nestedList: * | If ni.isInteger(): * | Add it to prev. * | Else: * | Add ni.getList() to next level. * Return previous sum + recursive call sum. */ private int dfs(List<NestedInteger> nestedList, int prev) { if (nestedList.isEmpty()) { return 0; } List<NestedInteger> nextLevel = new ArrayList<>(); for (NestedInteger ni : nestedList) { if (ni.isInteger()) { prev += ni.getInteger(); } else { nextLevel.addAll(ni.getList()); } } return prev + dfs(nextLevel, prev); } /** * DFS. Iterative. * Add integer in list multiple times. * Sum of current level is: sum of all integers in this level + sum of all integers in previous levels. * Iterate current list: * | For each NestedInteger in nestedList: * | If ni.isInteger(), add it to previous sum * | Else if ni is a list, add its list to next level * | Add prev to sum. * | nestedList = nextLevel * Return sum. */ public int depthSumInverseB(List<NestedInteger> nestedList) { int cur = 0, sum = 0; while (!nestedList.isEmpty()) { List<NestedInteger> nextLevel = new ArrayList<>(); for (NestedInteger ni : nestedList) { if (ni.isInteger()) { cur += ni.getInteger(); } else { nextLevel.addAll(ni.getList()); } } sum += cur; nestedList = nextLevel; } return sum; } }