给你一个二叉树的根节点 root
。设根节点位于二叉树的第 1
层,而根节点的子节点位于第 2
层,依此类推。
请返回层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 的那个。
示例 1:
![](https://assets.leetcode-cn.com/aliyun-lc- upload/uploads/2019/08/17/capture.jpeg)
**输入:** root = [1,7,0,7,-8,null,null]
**输出:** 2
**解释:**
第 1 层各元素之和为 1,
第 2 层各元素之和为 7 + 0 = 7,
第 3 层各元素之和为 7 + -8 = -1,
所以我们返回第 2 层的层号,它的层内元素之和最大。
示例 2:
**输入:** root = [989,null,10250,98693,-89388,null,null,null,-32127]
**输出:** 2
提示:
树中的节点数在 [1, 104]
范围内
-105 <= Node.val <= 105
方法一:深度优先搜索 我们可以采用深度优先搜索来遍历这棵二叉树,递归的同时记录当前的层号。
相比哈希表,这里我们采用效率更高的动态数组来维护每一层的元素之和,如果当前层号达到了数组的长度,则将节点元素添加到数组末尾,否则更新对应层号的元素之和。
然后遍历数组,找到元素之和最大,且层号最小的元素。
[sol1-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution : def maxLevelSum (self, root: Optional [TreeNode] ) -> int : sum = [] def dfs (node: TreeNode, level: int ) -> None : if level == len (sum ): sum .append(node.val) else : sum [level] += node.val if node.left: dfs(node.left, level + 1 ) if node.right: dfs(node.right, level + 1 ) dfs(root, 0 ) return sum .index(max (sum )) + 1
[sol1-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { vector<int > sum; void dfs (TreeNode *node, int level) { if (level == sum.size ()) { sum.push_back (node->val); } else { sum[level] += node->val; } if (node->left) { dfs (node->left, level + 1 ); } if (node->right) { dfs (node->right, level + 1 ); } } public : int maxLevelSum (TreeNode *root) { dfs (root, 0 ); int ans = 0 ; for (int i = 0 ; i < sum.size (); ++i) { if (sum[i] > sum[ans]) { ans = i; } } return ans + 1 ; } };
[sol1-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { private List<Integer> sum = new ArrayList <Integer>(); public int maxLevelSum (TreeNode root) { dfs(root, 0 ); int ans = 0 ; for (int i = 0 ; i < sum.size(); ++i) { if (sum.get(i) > sum.get(ans)) { ans = i; } } return ans + 1 ; } private void dfs (TreeNode node, int level) { if (level == sum.size()) { sum.add(node.val); } else { sum.set(level, sum.get(level) + node.val); } if (node.left != null ) { dfs(node.left, level + 1 ); } if (node.right != null ) { dfs(node.right, level + 1 ); } } }
[sol1-C#] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Solution { private IList<int > sum = new List<int >(); public int MaxLevelSum (TreeNode root ) { DFS(root, 0 ); int ans = 0 ; for (int i = 0 ; i < sum.Count; ++i) { if (sum[i] > sum[ans]) { ans = i; } } return ans + 1 ; } private void DFS (TreeNode node, int level ) { if (level == sum.Count) { sum.Add(node.val); } else { sum[level] += node.val; } if (node.left != null ) { DFS(node.left, level + 1 ); } if (node.right != null ) { DFS(node.right, level + 1 ); } } }
[sol1-Golang] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 func maxLevelSum (root *TreeNode) (ans int ) { sum := []int {} var dfs func (*TreeNode, int ) dfs = func (node *TreeNode, level int ) { if level == len (sum) { sum = append (sum, node.Val) } else { sum[level] += node.Val } if node.Left != nil { dfs(node.Left, level+1 ) } if node.Right != nil { dfs(node.Right, level+1 ) } } dfs(root, 0 ) for i, s := range sum { if s > sum[ans] { ans = i } } return ans + 1 }
[sol1-C] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #define MAX_NODE_SIZE 10000 void dfs (struct TreeNode *node, int level, int *sum, int *sumSize) { if (level == *sumSize) { sum[*sumSize] = node->val; (*sumSize)++; } else { sum[level] += node->val; } if (node->left) { dfs(node->left, level + 1 , sum, sumSize); } if (node->right) { dfs(node->right, level + 1 , sum, sumSize); } } int maxLevelSum (struct TreeNode* root) { int *sum = (int *)malloc (sizeof (int ) * MAX_NODE_SIZE); int sumSize = 0 ; dfs(root, 0 , sum, &sumSize); int ans = 0 ; for (int i = 0 ; i < sumSize; ++i) { if (sum[i] > sum[ans]) { ans = i; } } return ans + 1 ; }
[sol1-JavaScript] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var maxLevelSum = function (root ) { const sum = []; const dfs = (node, level ) => { if (level === sum.length ) { sum.push (node.val ); } else { sum.splice (level, 1 , sum[level] + node.val ); } if (node.left ) { dfs (node.left , level + 1 ); } if (node.right ) { dfs (node.right , level + 1 ); } } dfs (root, 0 ); let ans = 0 ; for (let i = 0 ; i < sum.length ; ++i) { if (sum[i] > sum[ans]) { ans = i; } } return ans + 1 ; };
复杂度分析
方法二:广度优先搜索 由于计算的是每层的元素之和,用广度优先搜索来遍历这棵树会更加自然。
对于广度优先搜索,我们可以用队列来实现。初始时,队列只包含根节点;然后不断出队,将子节点入队,直到队列为空。
如果直接套用方法一的思路,我们需要在队列中存储节点和节点的层号。另一种做法是一次遍历完一整层的节点,遍历的同时,累加该层的节点的元素之和,同时用这层的节点得到下一层的节点,这种做法不需要记录层号。
为了代码实现的方便,我们可以使用两个动态数组,第一个数组 q 为当前层的节点,第二个数组 nq 为下一层的节点。遍历 q 中节点的同时,把子节点加到 nq 中。遍历完当前层后,将 q 置为 nq。
[sol2-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution : def maxLevelSum (self, root: Optional [TreeNode] ) -> int : ans, maxSum = 1 , root.val level, q = 1 , [root] while q: sum , nq = 0 , [] for node in q: sum += node.val if node.left: nq.append(node.left) if node.right: nq.append(node.right) if sum > maxSum: ans, maxSum = level, sum q = nq level += 1 return ans
[sol2-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : int maxLevelSum (TreeNode *root) { int ans = 1 , maxSum = root->val; vector<TreeNode*> q = {root}; for (int level = 1 ; !q.empty (); ++level) { vector<TreeNode*> nq; int sum = 0 ; for (auto node : q) { sum += node->val; if (node->left) { nq.emplace_back (node->left); } if (node->right) { nq.emplace_back (node->right); } } if (sum > maxSum) { maxSum = sum; ans = level; } q = move (nq); } return ans; } };
[sol2-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int maxLevelSum (TreeNode root) { int ans = 1 , maxSum = root.val; List<TreeNode> q = new ArrayList <TreeNode>(); q.add(root); for (int level = 1 ; !q.isEmpty(); ++level) { List<TreeNode> nq = new ArrayList <TreeNode>(); int sum = 0 ; for (TreeNode node : q) { sum += node.val; if (node.left != null ) { nq.add(node.left); } if (node.right != null ) { nq.add(node.right); } } if (sum > maxSum) { maxSum = sum; ans = level; } q = nq; } return ans; } }
[sol2-C#] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Solution { public int MaxLevelSum (TreeNode root ) { int ans = 1 , maxSum = root.val; IList<TreeNode> q = new List<TreeNode>(); q.Add(root); for (int level = 1 ; q.Count > 0 ; ++level) { IList<TreeNode> nq = new List<TreeNode>(); int sum = 0 ; foreach (TreeNode node in q) { sum += node.val; if (node.left != null ) { nq.Add(node.left); } if (node.right != null ) { nq.Add(node.right); } } if (sum > maxSum) { maxSum = sum; ans = level; } q = nq; } return ans; } }
[sol2-Golang] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 func maxLevelSum (root *TreeNode) int { ans, maxSum := 1 , root.Val q := []*TreeNode{root} for level := 1 ; len (q) > 0 ; level++ { tmp := q q = nil sum := 0 for _, node := range tmp { sum += node.Val if node.Left != nil { q = append (q, node.Left) } if node.Right != nil { q = append (q, node.Right) } } if sum > maxSum { ans, maxSum = level, sum } } return ans }
[sol2-C] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #define MAX_NODE_SIZE 10000 int maxLevelSum (struct TreeNode* root) { int ans = 1 , maxSum = root->val; struct TreeNode **q = (struct TreeNode **)malloc (sizeof (struct TreeNode *) * MAX_NODE_SIZE); struct TreeNode **nq = (struct TreeNode **)malloc (sizeof (struct TreeNode *) * MAX_NODE_SIZE); int qSize = 0 ; q[qSize++] = root; for (int level = 1 ; qSize > 0 ; ++level) { int sum = 0 , nqSize = 0 ; for (int i = 0 ; i < qSize; i++) { sum += q[i]->val; if (q[i]->left) { nq[nqSize++] = q[i]->left; } if (q[i]->right) { nq[nqSize++] = q[i]->right; } } if (sum > maxSum) { maxSum = sum; ans = level; } struct TreeNode *tmp = q; q = nq; nq = tmp; qSize = nqSize; } free (q); free (nq); return ans; }
[sol2-JavaScript] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var maxLevelSum = function (root ) { let ans = 1 , maxSum = root.val ; let q = []; q.push (root); for (let level = 1 ; q.length > 0 ; ++level) { const nq = []; let sum = 0 ; for (const node of q) { sum += node.val ; if (node.left ) { nq.push (node.left ); } if (node.right ) { nq.push (node.right ); } } if (sum > maxSum) { maxSum = sum; ans = level; } q = nq; } return ans; };
复杂度分析