Nested List Weight Sum II
Given a nested list of integers, return the sum of all integers in the list weighted by their depth.
Each element is either an integer, or a list -- whose elements may also be integers or other lists.
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.
Example 1:
Given the list [[1,1],2,[1,1]], return 8. (four 1's at depth 1, one 2 at depth 2)
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)
follow up: one pass
The easiest way is to find maximum depth first then calculate sum.
A better one pass solution is to keep two variables: weighted and unweighted. When we traverse the list, if we find an integer, we add it to unweighted, otherwise we flatten it and add all its elements to the next level list. Finally we add unweighted to weighted. When we calculate the next level, since the sum of all elements in the upper level is still in unweighted, when we add it to weighted, we add the sum again, which is the depth sum we want.
The approach is actually a BFS approach (similarly to binary tree level order traversal)
public int depthSumInverse(List<nestedinteger> nestedList) { int weighted = 0, unweighted = 0; while (!nestedList.isEmpty()) { List<nestedinteger> nextLevel = new ArrayList<>(); for (NestedInteger nestedInteger : nestedList) { if (nestedInteger.isInteger()) { unweighted += nestedInteger.getInteger(); } else { nextLevel.addAll(nestedInteger.getList()); } } weighted += unweighted; nestedList = nextLevel; } return weighted; }
The idea is to pass the current found integer sum into the next level of recursion, and return it back again. So that we don't have to count the number of levels in the nested list.
I think code itself is quite self explanatory.
public class Solution { public int depthSumInverse(List<NestedInteger> nestedList) { return helper(nestedList, 0); } private int helper(List<NestedInteger> niList, int prev) { int intSum = prev; List<NestedInteger> levelBreak = new ArrayList<>(); for (NestedInteger ni : niList) { if (ni.isInteger()) { intSum += ni.getInteger(); } else { levelBreak.addAll(ni.getList()); } } int listSum = levelBreak.isEmpty()? 0 : helper(levelBreak, intSum); return listSum + intSum; } }
BFS, the time O(n), the space O(n)
public int depthSumInverse(List<NestedInteger> nestedList) { if (nestedList == null) return 0; Queue<NestedInteger> queue = new LinkedList<NestedInteger>(); int prev = 0; int total = 0; for (NestedInteger next: nestedList) { queue.offer(next); } while (!queue.isEmpty()) { int size = queue.size(); int levelSum = 0; for (int i = 0; i < size; i++) { NestedInteger current = queue.poll(); if (current.isInteger()) levelSum += current.getInteger(); List<NestedInteger> nextList = current.getList(); if (nextList != null) { for (NestedInteger next: nextList) { queue.offer(next); } } } prev += levelSum; total += prev; } return total; }
一定要验证input