吾日三省吾身
还记得梦想吗
正在努力实现它吗
可以坚持下去吗
目录
力扣题号:102. 二叉树的层序遍历 - 力扣(LeetCode)
力扣题号:102. 二叉树的层序遍历 - 力扣(LeetCode)
注:下述题目描述和示例均来自力扣
题目描述
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1] 输出:[[1]]
示例 3:
输入:root = [] 输出:[]
提示:
- 树中节点数目在范围
[0, 2000]
内 -1000 <= Node.val <= 1000
Java解法:二叉树的层序遍历
思路如下:
- 创建一个二维列表
res
用于存储最终结果。 - 若根节点为空,直接返回空列表
res
。 - 使用
ArrayDeque
实现的双端队列deque
,将根节点放入队列。 - 进入循环,每次循环处理一层的节点。
- 记录当前层需要遍历的节点数量
len
,以便在循环中遍历当前层的节点。 - 创建一个列表
one
用于存储当前层的节点值。 - 在内部循环中,弹出队列中的节点,并将其值添加到
one
列表中。 - 如果节点的左子节点存在,则将左子节点加入队列。
- 如果节点的右子节点存在,则将右子节点加入队列。
- 循环结束后,将
one
列表加入res
列表。
- 记录当前层需要遍历的节点数量
- 最终返回层序遍历的结果
res
。
实现思路
该算法通过使用双端队列(Deque)实现的队列来进行层序遍历。在每一层遍历时,记录当前层节点数以确保只遍历当前层的节点,并将节点值存储在一个列表中。将每一层的列表加入最终结果列表,最终返回完整的层序遍历结果。
注意事项
- 为了保证队列的长度不会在遍历过程中发生变化,使用一个变量
len
来记录每一层需要遍历的节点数。 - 算法使用了广度优先搜索(BFS)的思想,确保同一层的节点先被遍历,从而实现层序遍历的效果。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null){
return res;
}
Deque<TreeNode> deque = new ArrayDeque<>();
deque.offer(root);
while (!deque.isEmpty()){
// 记录一下这一层需要遍历的层数
// 为什么要在这里记录,因为队列的弹出会导致长度变化的
int len = deque.size();
// 定义一个list记录这一层的全部数据
List<Integer> one = new ArrayList<>();
for (int i = 0; i < len; i++) {
// 获取一个根节点
TreeNode node = deque.poll();
one.add(node.val);
// 判断是左右节点是否存在,如果存在就加入队列,下一层使用
if (node.left != null){
deque.offer(node.left);
}
if (node.right != null){
deque.offer(node.right);
}
}
// 一次len的循环就可以完成一层,一个list,加入res中即可
res.add(one);
}
return res;
}
}
不算太快哈,也没有打败全世界的人
C++解法:使用两个队列
思路如下:
- 创建一个二维向量
result
用于存储最终结果。 - 若根节点为空,直接返回空向量
result
。 - 使用两个队列
currentLevel
和nextLevel
分别表示当前层和下一层的节点。 - 将根节点放入
currentLevel
队列。 - 进入循环,每次循环处理一层的节点。
- 创建一个向量
levelValues
用于存储当前层的节点值。 - 在内部循环中,弹出
currentLevel
队列中的节点,并将其值添加到levelValues
向量中。 - 如果节点的左子节点不为空,将其加入
nextLevel
队列。 - 如果节点的右子节点不为空,将其加入
nextLevel
队列。 - 循环结束后,将
levelValues
向量加入result
向量。 - 通过交换
currentLevel
和nextLevel
,准备处理下一层的节点。
- 创建一个向量
- 最终返回层序遍历的结果
result
。
实现思路
该算法通过使用两个队列来避免在每一层的循环中进行队列的长度计算,提高了代码的效率。在每一层遍历时,使用两个队列交替存储当前层和下一层的节点,通过交换队列减少了不必要的操作。
注意事项
- 使用两个队列来交替存储当前层和下一层的节点,避免在每一层的循环中进行队列的长度计算,提高了代码的效率。
- 代码使用了队列来实现广度优先搜索(BFS)的思想,确保同一层的节点先被遍历,从而实现层序遍历的效果。
巧妙吧~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
if (!root) {
return result;
}
queue<TreeNode*> currentLevel;
queue<TreeNode*> nextLevel;
currentLevel.push(root);
while (!currentLevel.empty()) {
vector<int> levelValues;
while (!currentLevel.empty()) {
TreeNode* node = currentLevel.front();
currentLevel.pop();
levelValues.push_back(node->val);
if (node->left) {
nextLevel.push(node->left);
}
if (node->right) {
nextLevel.push(node->right);
}
}
result.push_back(levelValues);
swap(currentLevel, nextLevel);
}
return result;
}
};
总结
拿下喽,java的两个队列代码我就不提供了,反正已经拿下喽~~~
ヾ( ̄▽ ̄)Bye~Bye~