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. Vertica 高可用性测试

    1.基本概念介绍 2.停止某节点服务 3.测试其他节点访问 1.基本概念介绍 Vertica也是MPP架构的数据库,相比大家熟悉的MPP架构,比如Greenplum和hadoop这些产品,Vertic ...

  2. python获取命令行输出结果

    #coding=utf-8 import os   command = 'ping www.baidu.com ' #可以直接在命令行中执行的命令 r = os.popen(command) #执行该 ...

  3. 利用WCF的双工通讯实现一个简单的心跳监控系统

    何为心跳监控系统? 故名思义,就是监控某个或某些个程序的运行状态,就好比医院里面的心跳监视仪一样,能够随时显示病人的心跳情况. 心跳监控的目的是什么? 与医院里面的心跳监视仪目的类似,监控程序运行状态 ...

  4. Jsp的九大对象,七大动作,三大指令

    jsp九大内置对象:1>out 向客户端输出数据,字节流.如out.print(" dgaweyr"); 2>request 接收客户端的http请求.String g ...

  5. 自己封装的一个原生JS拖动方法。

    代码: function drag(t,p){ var point = p || null, target = t || null, resultX = 0, resultY = 0; (!point ...

  6. reStructuredText(rst)快速入门语法说明

    reStructuredText 是扩展名为.rst的纯文本文件,含义为"重新构建的文本"",也被简称为:RST或reST:是Python编程语言的Docutils项目的 ...

  7. Ionic2系列——使用DeepLinker实现指定页面URL

    Ionic2使用了近似原生App的页面导航方式,并不支持Angular2的路由.这种方式在开发本地App的时候比较方便,但如果要用来开发纯Web页面就有点问题了,这种情况下Angular2的route ...

  8. 使用图片视频展示插件blueimp Gallery改造网站的视频图片展示

    在很多情况下,我们网站可能会展示我们的产品图片.以及教程视频等内容,结合一个比较好的图片.视频展示插件,能够使得我们的站点更加方便使用,也更加酷炫,在Github上有很多相关的处理插件可以找来使用,有 ...

  9. C#多线程--线程池(ThreadPool)

    先引入一下线程池的概念: 百度百科:线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行, ...

  10. 【Java每日一题】20161227

    package Dec2016; public class Ques1227 { public static void main(String[] args){ } { c = 1; } int c ...