NestedListWeightSum [source code]
public class NestedListWeightSum {
public int depthSum(List<NestedInteger> nestedList) {
if (nestedList.size() == 0) return 0;
int res = 0;
for (NestedInteger i : nestedList) res += helper(1, i);
return res;
}
// This is the interface that allows for creating nested lists.
// You should not implement it, or speculate about its implementation
public interface NestedInteger {
// @return true if this NestedInteger holds a single integer, rather than a nested list.
public boolean isInteger();
// @return the single integer that this NestedInteger holds, if it holds a single integer
// Return null if this NestedInteger holds a nested list
public Integer getInteger();
// @return the nested list that this NestedInteger holds, if it holds a nested list
// Return null if this NestedInteger holds a single integer
public List<NestedInteger> getList();
}
public int helper(int accum, NestedInteger nestedInteger) {
if (nestedInteger.isInteger()) return accum * nestedInteger.getInteger();
int res = 0;
for (NestedInteger node : nestedInteger.getList()) res += helper(accum + 1, node);
return res;
}
}
读题的时候注意这句话:
return the sum of all integers in the list weighted by their depth
这个其实就是return weighted sum的意思, 不要以为就是简单的 sum;
另外注意这里这个NestedInteger的 API 的设计思路: 其实这个结构也是一个recursive definition, or inductive definition; base case就是 integer;
题外话, 如果这里的这个参数是一个 String, 这个问题其实是非常简单的, 直接从左到右扫一遍, 然后一个map 保存结果(可以用 array 如果知道这些 number 在某一个范围以内); 每个 number 的 weight 就是(按照 steam 算法的思路)扫到目前为止所出现的"["的个数减去"]"的个数. 这个算法真的是秒杀速度就想出来的.
这个题目其实跟一个普通的 tree 的问题非常类似;
分析的时候, 用小的例子开始分析, 比如[1,2]这样的;
刚开始的时候认为 helper 的参数也应该是List
这里碰到一个问题: 在意识到我对于 helper 的设计有问题的时候, 我就开始改. 但是因为不知道到底哪些地方要改, 我就先自己改了一个大概, 然后直接就丢到OJ 里面, 类似于让 compiler 来帮我改.
这个做法现在我是初期刷题阶段, 可能倒无所谓. 不过如果以后面类似 FG 这样的公司, 不停的compiler error肯定是说不过去的. 所以现在开始要养成自己眼睛扫一遍代码, 捕捉错误的习惯.
速度是2ms, 最优解的代码跟这个差不多, 都是fold right 的recursion. 之所以必须用FOLD_right, 是因为站在每一个root 自己的角度, 它能知道的其实只有自己往下的深度, 所以如果直接返回的 sum 是基于自己往下的深度计算出来的, 这个结果返回上去之后, 上面的 level 是没有办法使用的;
当然有一个折衷的办法, 就是还是一个普通的...好像没有折衷的办法(我想说的是一个普通的 traversal 走一遍, 记录深度withmap, 最后走一遍 map 来计算 sum);
另外这个问题, 类似于 tree 的问题, 也是可以用一个iterative BFS完成的, 下面是代码:
public int depthSum(List<NestedInteger> nestedList) {
if(nestedList == null){
return 0;
}
int sum = 0;
int level = 1;
Queue<NestedInteger> queue = new LinkedList<NestedInteger>(nestedList);
while (queue.size() > 0) {
int size = queue.size();
for (int i = 0; i < size; i++) {
NestedInteger ni = queue.poll();
if (ni.isInteger()) {
sum += ni.getInteger() * level;
} else {
queue.addAll(ni.getList());
}
}
level++;
}
return sum;
}
事实上, BFS 是这类问题最 intuitive 的思路, 不过写的时候可能有点麻烦就是了;
反过头来想想, 这个问题跟之前的max depth of binary tree有什么不同的地方? 导致那个题目就可以用left fold, 这里就只能用right fold? 我感觉主要的区别就是left fold无法完成乘法, 只能完成加法;
好像其实我这个跟fold left/right没有什么关系? 好像记混淆概念了. 那就用 accum 思路来记忆好了. 反正就是如果涉及加法以外的计算, 很可能不实用 accum 就没有办法完成了(?有待考证);
Problem Description
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.
Example 1:
Given the list [[1,1],2,[1,1]], return 10. (four 1's at depth 2, one 2 at depth 1)
Example 2:
Given the list [1,[4,[6]]], return 27. (one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 42 + 63 = 27)
Hide Company Tags LinkedIn
Hide Tags Depth-first Search
Hide Similar Problems (M) Nested List Weight Sum II (M) Array Nesting