「这是我参与2022首次更文挑战的第34天,活动详情查看:2022首次更文挑战」。
题目:给定一颗二叉树,要求返回此二叉树的层序遍历。即逐层从左向右访问所有的节点。
解题思路
本题较为简单,从左向右层序访问节点,这就要求我们先访问根节点,之后将左右节点进行处理。利用队列先进先出的特性,我们可以通过队列来存储中间节点,例如先将根节点加入队列,之后每次从队列中弹出一个节点,弹出这个节点就对此节点进行处理,处理之后将该节点的左孩子和右孩子入队列,依次循环遍历即可。
上面的思路可以依次输出一棵树的层序遍历结果,本题相对比较难的是如何确定哪些节点属于同一层,思路也很巧妙,可以在第一个元素入队的时候,设置一个变量保存队列中元素的个数,每次出队都将该变量减一,最后如果该变量为0则代表某一层的节点遍历完成,此时就可以将临时结果加入最终结果。代码如下:
public List<List<Integer>> levelOrder(TreeNode root) {
if(root==null) return new ArrayList<>();
LinkedList<TreeNode> queue = new LinkedList<>();
ArrayList<List<Integer>> res = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
queue.offer(root);
int size=1;
while(!queue.isEmpty()){
root = queue.poll();
temp.add(root.val);
size--;
if(root.left!=null){
queue.offer(root.left);
}
if(root.right!=null){
queue.offer(root.right);
}
if(size==0){
res.add(temp);
temp = new ArrayList<Integer>();
size = queue.size();
}
}
return res;
}
时间复杂度和空间复杂度都为。
二叉树的层序遍历还可以确定二叉树的最大宽度和二叉树的最大深度,例如下面LeetCode 104题的求二叉树的最大深度。
二叉树的最大深度
最大深度的求解一种思路和上面层序遍历类似,关键思路就是利用size来记录,如果size等于0,则代表本层结束,此时可以使用另一个变量来自增作为二叉树的高度。当然宽度也是取决于size,如果size等于0,那么此时队列中的节点就可以通过索引值来获取最大宽度,所不同的是此时队列入队的不是节点,而是编码后的节点索引。最大深度的代码如下:
public int maxDepth(TreeNode root) {
if(root==null) return 0;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int size=1;
int maxDepth=0;
while (!queue.isEmpty()){
root = queue.poll();
size--;
if(root.left!=null) queue.offer(root.left);
if(root.right!=null) queue.offer(root.right);
if(size==0){
maxDepth++;
size = queue.size();
}
}
return maxDepth;
}
上述代码时间复杂度和空间复杂度都是。
另一种求最大深度的思路是使用递归,因为二叉树的最大高度取决于左右子树的最大高度+1,而左右子树也可以同样计算,因此可得如下代码:
public int maxDepth(TreeNode root) {
return root==null?0:Math.max(maxDepth(root.left), maxDepth(root.right))+1;
}