小白刷代码随想录day15--二叉树层序遍历及十题(102,107,199,637,429,515,116,117,104,111)

二叉树层序遍历

层序遍历--广度优先搜索

看卡哥视频:讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历

学会可以打10题:102,107,199,637,429,515,116,117,104,111

102. 二叉树的层序遍历

题目

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

题目

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. 二叉树的右视图

题目

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.二叉树的层平均值

题目

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值