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:

Input: [[1,1],2,[1,1]]
Output: 8
Explanation: Four 1's at depth 1, one 2 at depth 2.

Example 2:

Input: [1,[4,[6]]]
Output: 17
Explanation: One 1 at depth 3, one 4 at depth 2, and one 6 at depth 1; 1*3 + 4*2 + 6*1 = 17.

这道题是之前那道 Nested List Weight Sum 的拓展,与其不同的是,这里的深度越深,权重越小,和之前刚好相反。但是解题思路没有变,还可以用 DFS 来做,由于遍历的时候不知道最终的 depth 有多深,则不能遍历的时候就直接累加结果,博主最开始的想法是在遍历的过程中建立一个二维数组,把每层的数字都保存起来,然后最后知道了 depth 后,再来计算权重和,比如题目中给的两个例子,建立的二维数组分别为:

[[1,1],2,[1,1]]:

1 1 1 1
2

[1,[4,[6]]]:

1
4
6

这样我们就能算出权重和了,参见代码如下:

解法一:

class Solution {
public:
int depthSumInverse(vector<NestedInteger>& nestedList) {
int res = ;
vector<vector<int>> all;
for (auto &a : nestedList) {
helper(a, , all);
}
for (int i = (int)all.size() - ; i >= ; --i) {
for (int j = ; j < all[i].size(); ++j) {
res += all[i][j] * ((int)all.size() - i);
}
}
return res;
}
void helper(NestedInteger& ni, int depth, vector<vector<int>>& all) {
vector<int> t;
if (depth < all.size()) t = all[depth];
else all.push_back(t);
if (ni.isInteger()) {
t.push_back(ni.getInteger());
all[depth] = t;
} else {
for (auto &a : ni.getList()) {
helper(a, depth + , all);
}
}
}
};

其实上面的方法可以简化,由于每一层的数字不用分别保存,每个数字分别乘以深度再相加,跟每层数字先相加起来再乘以深度是一样的,这样只需要一个一维数组就可以了,只要把各层的数字和保存起来,最后再计算权重和即可:

解法二:

class Solution {
public:
int depthSumInverse(vector<NestedInteger>& nestedList) {
int res = ;
vector<int> v;
for (auto &a : nestedList) {
helper(a, , v);
}
for (int i = (int)v.size() - ; i >= ; --i) {
res += v[i] * ((int)v.size() - i);
}
return res;
}
void helper(NestedInteger& ni, int depth, vector<int>& v) {
if (depth >= v.size()) v.resize(depth + );
if (ni.isInteger()) {
v[depth] += ni.getInteger();
} else {
for (auto &a : ni.getList()) {
helper(a, depth + , v);
}
}
}
};

下面这个方法就比较巧妙了,由史蒂芬大神提出来的,这个方法用了两个变量 unweighted 和 weighted,非权重和跟权重和,初始化均为0,然后如果 nestedList 不为空开始循环,先声明一个空数组 nextLevel,遍历 nestedList 中的元素,如果是数字,则非权重和加上这个数字,如果是数组,就加入 nextLevel,这样遍历完成后,第一层的数字和保存在非权重和 unweighted 中了,其余元素都存入了 nextLevel 中,此时将 unweighted 加到 weighted 中,将 nextLevel 赋给 nestedList,这样再进入下一层计算,由于上一层的值还在 unweighted 中,所以第二层计算完将 unweighted 加入 weighted 中时,相当于第一层的数字和被加了两次,这样就完美的符合要求了,这个思路又巧妙又牛B,大神就是大神啊,参见代码如下:

解法三:

class Solution {
public:
int depthSumInverse(vector<NestedInteger>& nestedList) {
int unweighted = , weighted = ;
while (!nestedList.empty()) {
vector<NestedInteger> nextLevel;
for (auto a : nestedList) {
if (a.isInteger()) {
unweighted += a.getInteger();
} else {
nextLevel.insert(nextLevel.end(), a.getList().begin(), a.getList().end());
}
}
weighted += unweighted;
nestedList = nextLevel;
}
return weighted;
}
};

下面这种算法是常规的 BFS 解法,利用上面的建立两个变量 unweighted 和 weighted 的思路,大体上没什么区别:

解法四:

class Solution {
public:
int depthSumInverse(vector<NestedInteger>& nestedList) {
int unweighted = , weighted = ;
queue<vector<NestedInteger>> q;
q.push(nestedList);
while (!q.empty()) {
int size = q.size();
for (int i = ; i < size; ++i) {
vector<NestedInteger> t = q.front(); q.pop();
for (auto a : t) {
if (a.isInteger()) unweighted += a.getInteger();
else if (!a.getList().empty()) q.push(a.getList());
}
}
weighted += unweighted;
}
return weighted;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/364

类似题目:

Nested List Weight Sum

Array Nesting

参考资料:

https://leetcode.com/problems/nested-list-weight-sum-ii/

https://leetcode.com/problems/nested-list-weight-sum-ii/discuss/83655/JAVA-AC-BFS-solution

https://leetcode.com/problems/nested-list-weight-sum-ii/discuss/83641/No-depth-variable-no-multiplication

https://leetcode.com/problems/nested-list-weight-sum-ii/discuss/114195/Java-one-pass-DFS-solution-mathematically

https://leetcode.com/problems/nested-list-weight-sum-ii/discuss/83649/Share-my-2ms-intuitive-one-pass-no-multiplication-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Nested List Weight Sum II 嵌套链表权重和之二的更多相关文章

  1. [LeetCode] 364. Nested List Weight Sum II 嵌套链表权重和之二

    Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...

  2. [leetcode]364. Nested List Weight Sum II嵌套列表加权和II

    Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...

  3. Leetcode: Nested List Weight Sum II

    Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...

  4. LeetCode Nested List Weight Sum

    原题链接在这里:https://leetcode.com/problems/nested-list-weight-sum/ 题目: Given a nested list of integers, r ...

  5. LeetCode 364. Nested List Weight Sum II

    原题链接在这里:https://leetcode.com/problems/nested-list-weight-sum-ii/description/ 题目: Given a nested list ...

  6. [LeetCode] Nested List Weight Sum 嵌套链表权重和

    Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...

  7. LeetCode 339. Nested List Weight Sum (嵌套列表重和)$

    Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...

  8. 【LeetCode】364. Nested List Weight Sum II 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...

  9. 364. Nested List Weight Sum II 大小反向的括号加权求和

    [抄题]: Given a nested list of integers, return the sum of all integers in the list weighted by their ...

随机推荐

  1. css随笔记

    使用伪类写边框部分三角 右上角三角形 border-top:6px solid #c1ddf7 border-left:6px solid transparent 右下角三角形 border-bott ...

  2. TCP四种计时器

    TCP共使用以下四种计时器,即重传计时器.坚持计时器.保活计时器和时间等待计时器 .这几个计时器的主要特点如下:      1.重传计时器      当TCP发送报文段时,就创建该特定报文段的重传计时 ...

  3. WinServer2008R2 + IIS 7.5 + .NET4.0 经典模式 运行WebAPI程序报404错误的解决方案

    在Windows Server 2008 R2系统下,IIS 7.5 + .NET Framework 4.0的运行环境,以经典模式(Classic Mode)部署一个用.NET 4.0编译的 Web ...

  4. TabControl 伸缩式菜单 仿照 uwp SplitView

    留下备用笔记 之前用的Frame+Page的切换content<类似于一个contentControl 干多个事情>,但是发现页面content内容控件多的时候,每一次切换都有点卡,点击了 ...

  5. thinkphp怎么修改配置进入默认首页

    thinkphp文件夹下config 里面有个convention.php文件 里面有三个配置 'DEFAULT_MODULE' => 'Home', // 默认模块 'DEFAULT_CONT ...

  6. 分布式搜索elasticsearch配置文件详解

    elasticsearch的config文件夹里面有两个配置文件:elasticsearch.yml和logging.yml,第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来 ...

  7. canvas调用scale或者drawImage图片操作后,锯齿感很明显的解决

    <script type="text/javascript"> //解决canvas画画图片 var mengvalue = -1; var phoneWidth = ...

  8. python入门-python解释器执行

    最近由于公司需要,接触了python这门神奇的语言,给我的感觉就是开发快速和代码简洁. 开始还是先罗列一下解释性语言和编译性语言的差别吧0.0!   编译性语言:是在程序运行前,需要专门的一个编译过程 ...

  9. 浏览器对localstorage的支持情况以及localstorage在saas系统中的应用实践思考

    首先,还是要说,任何一种新特性的引入,通常有着其特有的场景和解决的目标需求,localstorage也一样.在我们的应用场景中,主要在金融业务服务的saas系统.其中涉及很多更改频率很多的元数据的客户 ...

  10. Angular的自定义指令以及实例

    本文章已收录于:  AngularJS知识库  分类: javascript(55)  http://www.cnblogs.com/xiaoxie53/p/5058198.html   前面的文章介 ...