目录
前言
一、只用一个队列
二、使用两个队列
前言
题目链接:LCR 044. 在每个树行中找最大值 - 力扣(LeetCode)
题目:
输入一棵二叉树,请找出二叉树中每层的最大值。例如,输入下图中的二叉树,返回各层节点的最大值 [3, 4, 9]。
分析:
这个题目提到了二叉树的层。既然要找出二叉树中每层的最大值,就要逐层遍历二叉树,也就是说,按照广度优先的顺序遍历二叉树。
一、只用一个队列
由于要找出二叉树中每层的最大值,因此在遍历时需要知道每层什么时候开始、什么时候结束。如果只用一个队列来保存尚未遍历到的节点,那么有可能位于不同的两层的节点同时在队列之中。例如,遍历到节点 4 时,就把节点 4 从队列中取出来,此时节点 2 已经在队列中。接下来要把节点 4 的两个子节点(节点 5 和节点 1)都添加到队列中。这个时候第 2 层的节点 2 和第 3 层的节点 5、节点 1 都在队列中。
如果不同的两层的节点同时位于队列之中,那么每次从队列之中取出节点来遍历时就需要知道这个节点位于哪一层。解决这个问题的一个办法是计数。
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
queue<TreeNode*> q;
int curLevelSize = 0;
if (root)
{
q.push(root);
curLevelSize = 1;
}
vector<int> result;
while (!q.empty())
{
int max = INT_MIN;
while (curLevelSize--)
{
TreeNode* front = q.front();
q.pop();
if (front->val > max)
max = front->val;
if (front->left)
q.push(front->left);
if (front->right)
q.push(front->right);
}
result.push_back(max);
curLevelSize = q.size();
}
return result;
}
};
二、使用两个队列
另一个办法是用两个不同的队列 q1 和 q1 分别存放不同的两层的节点,队列 q1 中只放当前遍历层的节点,而队列 q2 中只放下一层的节点。
最开始时把二叉树的根节点放入队列 q1 中。接下来每次从队列中取出一个节点遍历。由于队列 q1 用来存放当前遍历层的节点,因此总是从队列 q1 中取出节点用来遍历。如果当前遍历的节点有子节点,则把子节点都放入队列 q2 中。
当队列 q1 被清空时,当前层的所有节点都已经被遍历完。通过比较这一层所有节点的值,就能找出这一层所有节点的最大值。在开始遍历下一层之前,把队列 q1 指向队列 q2,并将队列 q2 重新初始化为空的队列。重复这个过程,直到所有节点都遍历完为止。
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
queue<TreeNode*> q1, q2;
if (root)
q1.push(root);
vector<int> result;
int max = INT_MIN;
while (!q1.empty())
{
TreeNode* front = q1.front();
q1.pop();
if (front->val > max)
max = front->val;
if (front->left)
q2.push(front->left);
if (front->right)
q2.push(front->right);
if (q1.empty())
{
result.push_back(max);
max = INT_MIN;
q1 = q2;
q2 = queue<TreeNode*>();
}
}
return result;
}
};