[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.
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) 

这道题是之前那道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 = 0;
        vector<vector<int>> v;
        for (auto a : nestedList) {
            helper(a, 0, v);
        }
        for (int i = v.size() - 1; i >= 0; --i) {
            for (int j = 0; j < v[i].size(); ++j) {
                res += v[i][j] * (v.size() - i);
            }
        }
        return res;
    }
    void helper(NestedInteger &ni, int depth, vector<vector<int>> &v) {
        vector<int> t;
        if (depth < v.size()) t = v[depth];
        else v.push_back(t);
        if (ni.isInteger()) {
            t.push_back(ni.getInteger());
            if (depth < v.size()) v[depth] = t;
            else v.push_back(t);
        } else {
            for (auto a : ni.getList()) {
                helper(a, depth + 1, v);
            }
        }
    }
};

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

解法二:

class Solution {
public:
    int depthSumInverse(vector<NestedInteger>& nestedList) {
        int res = 0;
        vector<int> v;
        for (auto a : nestedList) {
            helper(a, 0, v);
        }
        for (int i = v.size() - 1; i >= 0; --i) {
            res += v[i] * (v.size() - i);
        }
        return res;
    }
    void helper(NestedInteger ni, int depth, vector<int> &v) {
        if (depth >= v.size()) v.resize(depth + 1);
        if (ni.isInteger()) {
            v[depth] += ni.getInteger();
        } else {
            for (auto a : ni.getList()) {
                helper(a, depth + 1, 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 = 0, weighted = 0;
        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 = 0, weighted = 0;
        queue<vector<NestedInteger>> q;
        q.push(nestedList);
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; 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;
    }
};

本文转自博客园Grandyang的博客,原文链接:嵌套链表权重和之二[LeetCode] Nested List Weight Sum II ,如需转载请自行联系原博主。

相关文章
|
1月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
35 1
|
1月前
Leetcode第21题(合并两个有序链表)
这篇文章介绍了如何使用非递归和递归方法解决LeetCode第21题,即合并两个有序链表的问题。
48 0
Leetcode第21题(合并两个有序链表)
|
1月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
18 0
LeetCode第二十四题(两两交换链表中的节点)
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
44 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
|
索引
力扣(LeetCode)数据结构练习题(3)------链表
力扣(LeetCode)数据结构练习题(3)------链表
78 0
|
1月前
【LeetCode 10】142. 环形链表 II
【LeetCode 10】142. 环形链表 II
21 0
|
1月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
17 0
|
1月前
【LeetCode 08】206 反转链表
【LeetCode 08】206 反转链表
12 0
|
1月前
【LeetCode 06】203.移除链表元素
【LeetCode 06】203.移除链表元素
29 0
|
3月前
|
C++ 索引
leetcode 707.设计链表
本文提供了解决LeetCode 707题"设计链表"的C++实现,包括单链表的节点定义和类方法实现,如添加节点、获取节点值、删除节点等。
下一篇
无影云桌面