1. 程式人生 > 其它 >[LeetCode] 1161. Maximum Level Sum of a Binary Tree 最大層內元素和

[LeetCode] 1161. Maximum Level Sum of a Binary Tree 最大層內元素和


Given therootof a binary tree, the level of its root is1, the level of its children is2, and so on.

Return thesmallestlevelxsuch that the sum of all the values of nodes at levelxismaximal.

Example 1:

Input: root = [1,7,0,7,-8,null,null]
Output: 2
Explanation:
Level 1 sum = 1.
Level 2 sum = 7 + 0 = 7.
Level 3 sum = 7 + -8 = -1.
So we return the level with the maximum sum which is level 2.

Example 2:

Input: root = [989,null,10250,98693,-89388,null,null,null,-32127]
Output: 2

Constraints:

  • The number of nodes in the tree is in the range[1, 104].
  • -105<= Node.val <= 105

這道題說是給了一棵二叉樹,根結點是層數1,其子結點是層數2,依次類推,讓找到最小的層數,使得該層上的結點值之和最大。這裡所謂的最小的層數,實際上就是說當層結點值之和相同的時候,取層數較小的層。說白了這道題的難點就是如何求每一層的結點值之和,肯定需要遍歷整個二叉樹,用什麼樣的遍歷方式呢,當然是用層序最方便啦,LeetCode 中有考察層序遍歷的題,

Binary Tree Level Order Traversal
Binary Tree Level Order Traversal II,做過這兩道的話,這道題也就沒啥難度了。這裡還是用 queue 來輔助遍歷,先將根結點放入佇列,然後開始 while 迴圈遍歷,先將初始化為0的 level 自增1,因為根結點是層數1。因為當前 queue 裡的所有結點都屬於同一層,需要一起遍歷完,為了防止後來新加入 queue 的結點汙染,這裡用個 for 迴圈遍歷當前層的所有結點,注意 q.size() 必須放在初始化裡,而不能是判斷條件裡,因為其會改變,累加每層所有的結點值之和到 sum,然後跟全域性的 mx 對比,若 sum 大於 mx,則更新 sum 為 mx,同時更新 res 為當前層數,參見程式碼如下:


解法一:

class Solution {
public:
    int maxLevelSum(TreeNode* root) {
        int res = 1, mx = root->val, level = 0;
        queue<TreeNode*> q{{root}};
        while (!q.empty()) {
            ++level;
            int sum = 0;
            for (int i = q.size(); i > 0; --i) {
                TreeNode* t = q.front(); q.pop();
                sum += t->val;
                if (t->left) q.push(t->left);
                if (t->right) q.push(t->right);
            }
            if (mx < sum) {
                mx = sum;
                res = level;
            }
        }
        return res;
    }
};

我們也可以強行用遞迴來做,由於層數可能一直會變,所以用一個數組 sums 來記錄每一層的結點值之和。在遞迴函式中,若結點為空,直接返回。否則看若 sums 的大小於 level,說明應該增加 sums 的大小,用個 resize 來增加。然後就把當前結點值加入到 sums[level-1] 中,再分別對左右子結點呼叫遞迴函式即可。sums 陣列更新好了,需要找到其中的最大值的位置,這裡使用了一些 STL 內建的函式來做,用 max_element 來找最大值,用 distance 來求和第一個數字之間的距離,最後再加1即可,參見程式碼如下:


解法二:

class Solution {
public:
    int maxLevelSum(TreeNode* root) {
        vector<int> sums;
        helper(root, 1, sums);
        return distance(begin(sums), max_element(begin(sums), end(sums))) + 1;
    }
    void helper(TreeNode* node, int level, vector<int>& sums) {
        if (!node) return;
        if (sums.size() < level) sums.resize(level);
        sums[level - 1] += node->val;
        helper(node->left, level + 1, sums);
        helper(node->right, level + 1, sums);
    }
};

Github 同步地址:

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


類似題目:

Binary Tree Level Order Traversal

Binary Tree Level Order Traversal II


參考資料:

https://leetcode.com/problems/maximum-level-sum-of-a-binary-tree/

https://leetcode.com/problems/maximum-level-sum-of-a-binary-tree/discuss/360968/JavaPython-3-Two-codes-language%3A-BFS-level-traversal-and-DFS-level-sum.

https://leetcode.com/problems/maximum-level-sum-of-a-binary-tree/discuss/360973/C%2B%2B-track-level-sum


LeetCode All in One 題目講解彙總(持續更新中...)