二叉树层序遍历
层序遍历--广度优先搜索
看卡哥视频:讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历
学会可以打10题:102,107,199,637,429,515,116,117,104,111
102. 二叉树的层序遍历
题目
代码
/**
* 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>> result = new ArrayList<List<Integer>>();
//借用队列
Queue<TreeNode> que;
que = new LinkedList<TreeNode>();
if(root != null){
que.offer(root);
}
while(!que.isEmpty()){ //遍历终止条件:队列为空
int size = que.size(); //记录本层节点数
List<Integer> arr = new ArrayList<Integer>(); //记录一层里面的所有节点
while(size-- > 0){ //当size为0时本层遍历结束
TreeNode node = que.peek(); //队头元素
que.poll(); //推出队头元素
arr.add(node.val); //将该元素的值存入数组
//加入孩子(下一层)
if(node.left != null){
que.offer(node.left);
}
if(node.right != null){
que.offer(node.right);
}
}
result.add(arr); //把一层的元素放入结果数组
}
return result;
}
}
107. 二叉树的层序遍历II
题目
代码
class Solution {
/**
* 解法:队列,迭代。
* 层序遍历,再翻转数组即可。
*/
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> resList = new ArrayList<List<Integer>>();
Queue<TreeNode> que = new LinkedList<TreeNode>();
if(root == null) return resList;
que.offer(root);
while(!que.isEmpty()){
int size = que.size(); //记录本层节点数
List<Integer> itemList = new ArrayList<Integer>(); //记录本层
while(size-- >0){
TreeNode node = que.poll();
itemList.add(node.val);
if(node.left != null) que.offer(node.left);
if(node.right != null) que.offer(node.right);
}
resList.add(itemList); //将记录本层节点的数组加入结果数组
}
/**翻转数组 */
List<List<Integer>> result = new ArrayList<List<Integer>>();
int n = resList.size();
for(int i =n - 1; i >= 0; i--){
result.add(resList.get(i));
}
return result;
}
}
/**
* 思路和模板相同, 对收集答案的方式做了优化, 最后不需要反转
*/
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
// 利用链表可以进行 O(1) 头部插入, 这样最后答案不需要再反转
LinkedList<List<Integer>> ans = new LinkedList<>();
Queue<TreeNode> q = new LinkedList<>();
if (root != null) q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
List<Integer> temp = new ArrayList<>();
for (int i = 0; i < size; i ++) {
TreeNode node = q.poll();
temp.add(node.val);
if (node.left != null) q.offer(node.left);
if (node.right != null) q.offer(node.right);
}
// 新遍历到的层插到头部, 这样就满足按照层次反序的要求
ans.addFirst(temp);
}
return ans;
}
}
199. 二叉树的右视图
题目
代码
错误解答:
错误原因:右视图不等于只有右边的节点!!!
只遍历了右节点,而右视图并不只包含右节点。当没有右子树时就能看到左子树了。所以应该返回着一层的最后一个节点而不是右节点。
class Solution {
public List<Integer> rightSideView(TreeNode root) {
/**层序遍历,只把右节点加入队列 */ (错❌)
//List<List<Integer>> resList = new ArrayList<List<Integer>>();
List<Integer> resList = new ArrayList<Integer>();
if(root == null) return resList;
//若root不为null,将root加入队列
Queue<TreeNode> que = new LinkedList<TreeNode>();
que.offer(root);
while(!que.isEmpty()){
int size = que.size(); //存放加入层的节点数
//List<Integer> itemList = new ArrayList<Integer>(); //数组存放加入层的节点的值
while(size-- >0){
//当size = 0 时,本层已全部存入,跳出遍历开始下一层
//当size >0 时(每次循环size-1):
TreeNode node = que.poll(); //从que中推出一个节点,记为node
//itemList.add(node.val); //将node节点的值存入数组
resList.add(node.val); //将node节点的值存入数组
//que中推入node节点的孩子(本题只放右孩子)
if(node.right != null) que.offer(node.right);
}
//resList.add(itemList);
}
return resList;
}
}
正确解答:
637.二叉树的层平均值
题目
代码
本来想着直接用list自带的ave方法,但可能是没有这个方法或者在这里没法用。应该用 sum/size 计算average。
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> aveList= new ArrayList<Double>();
Queue<TreeNode> que = new LinkedList<TreeNode>();
if(root == null) return aveList;
que.offer(root);
while(!que.isEmpty()){
int size = que.size();
double sum = 0; //存放每一层节点的和
//List<Double> tempList = new ArrayList<Double>(); //存放每层元素
//while(size-- >0){
//这里最好用if遍历,因为size最好不要变,后面还要用来计算平均值
for(int i =0; i < size; i++){
TreeNode node = que.poll();
sum += node.val;
//tempList.add(node.val);
if(node.left != null) que.offer(node.left);
if(node.right != null) que.offer(node.right);
}
double average = sum / size;
aveList.add(average);
}
return aveList;
}
}
后续任务:
二叉树层序遍历(429,515,116,117,104,111 )
226. 翻转二叉树(优先掌握递归)
题目链接/文章讲解/视频讲解:https://programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html
101.对称二叉树(优先掌握递归)
题目链接/文章讲解/视频讲解:https://programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html