1. 程式人生 > >[LeetCode] Nested List Weight Sum II 巢狀連結串列權重和之二

[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;
    }
};

類似題目:

參考資料: