算法通关村第6关【白银】| 树的层次遍历问题

一、基本层次遍历问题

1.二叉树的层次遍历

思路:使用队列可以很好的保存遍历状态,出队将结点左右子结点入队,用size记录下一层的元素个数,这样就能区分出层了

java 复制代码
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root == null){
            return new LinkedList<>();
        }
        List<List<Integer>> res = new LinkedList<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.addFirst(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            LinkedList<Integer> list = new LinkedList<>();
            while(size>0){
                TreeNode node = queue.remove();
                list.addLast(node.val);
                if(node.left != null){
                    queue.addLast(node.left);
                }
                if(node.right != null){
                    queue.addLast(node.right);
                }
                size--;
            }
            res.add(list);
        }
        return res;
        
    }
}

2.二叉树的层次遍历II

思路:此题和上一题大同小异,只需要在添加结果集的时候头插法就可以了。

java 复制代码
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        if(root == null){
            return new LinkedList<>();
        }
        List<List<Integer>> res = new LinkedList<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            List<Integer> list = new LinkedList<>();
            while(size>0){
                TreeNode node = queue.removeFirst();
                size--;
                list.add(node.val);
                if(node.left!= null){
                    queue.add(node.left);
                }
                if(node.right!= null){
                    queue.add(node.right);
                }
            }
            res.add(0,list);
        }
        return res;
    }
}

3.锯齿形遍历

思路:和层次遍历不同的是每层顺序奇偶方向交替,用一个变量记录当前层的变量规则,从左往右就是尾插法,从右往左就是头插法

java 复制代码
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        if(root == null){
            return new LinkedList<>();
        }
        List<List<Integer>> res = new LinkedList<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        int loop = 1;
        while(!queue.isEmpty()){
            int size = queue.size();
            LinkedList<Integer> list = new LinkedList<>();
            for(int i = 0;i<size;i++){
                TreeNode node = queue.removeFirst();
                if(node.left!= null){
                    queue.add(node.left);
                }   
                if(node.right!= null){
                    queue.add(node.right);
                }
                if(loop%2==0){
                    list.addFirst(node.val);
                }else{
                    list.add(node.val);
                }
                
            }
            res.add(list);
            loop++;
        }
        return res;
    }
}

4.N叉树的层次遍历

思路:此题和基本层次遍历不同的是,每次不是添加左右孩子入队而是添加孩子列表入队,把添加左右孩子替换成遍历添加列表就成。

java 复制代码
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        if(root == null){
            return new LinkedList<>();
        }
        List<List<Integer>> res = new LinkedList<>();
        LinkedList<Node> queue = new LinkedList<>();
        queue.addFirst(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            LinkedList<Integer> list = new LinkedList<>();
            while(size>0){
                Node node = queue.remove();
                list.addLast(node.val);
                for(Node child : node.children){
                    queue.add(child);
                }
                size--;
            }
            res.add(list);
        }
        return res;
    }
}

二、处理每层元素的问题

1.在每个树行中找最大值

思路:还是和遍历大同小异,现在不是将所有子结点都加入结果,只取每层最大的,比较一下就行

java 复制代码
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        if(root == null){
            return new LinkedList<>();
        }
        List<Integer> res = new LinkedList<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.addFirst(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            int max = Integer.MIN_VALUE;
            while(size>0){
                TreeNode node = queue.remove();
                if(node.val>max){
                    max = node.val;
                }
                if(node.left != null){
                    queue.addLast(node.left);
                }
                if(node.right != null){
                    queue.addLast(node.right);
                }
                size--;
            }
            res.add(max);
        }
        return res;
    }
}

2.每个树行的平均值

思路:和上一题找最大值没什么差别,每层相加除以size就可以。

java 复制代码
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        if(root == null){
            return new LinkedList<>();
        }
        List<Double> res = new LinkedList<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.addFirst(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            Double mean = 0.0;
            for(int i = 0;i<size;i++){
                TreeNode node = queue.remove();
                mean += node.val;
                if(node.left != null){
                    queue.addLast(node.left);
                }
                if(node.right != null){
                    queue.addLast(node.right);
                }
                
            }
            res.add(mean/size);
        }
        return res;
    }
}

3.二叉树的右视图

思路:层次遍历,最后一个元素加入结果集就行。

java 复制代码
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        if(root == null){
            return new LinkedList<>();
        }
        List<Integer> res = new LinkedList<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.addFirst(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            TreeNode node = root;
            while(size>0){
                node = queue.remove();
                if(node.left != null){
                    queue.addLast(node.left);
                }
                if(node.right != null){
                    queue.addLast(node.right);
                }
                size--;
            }
            res.add(node.val);
        }
        return res;
    }
}

4.找树最小角的值

思路:1)层次遍历,记录下每层第一个元素

2)从右往左层次遍历,最后一个元素

java 复制代码
//方法一
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        if(root == null){
            return -1;
        }
        int res = -1;
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(queue.size()>0){
            int size = queue.size();
            res = queue.get(0).val;
            while(size>0){
                TreeNode node = queue.remove();
                size--;
                if(node.left != null){
                    queue.add(node.left);
                }
                if(node.right != null){
                    queue.add(node.right);
                }
            }
        }
        return res;
    }
}

//方法二
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        if(root == null){
            return -1;
        }
        int res = -1;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            TreeNode node = queue.poll();
            res = node.val;
            if(node.right != null){
                queue.offer(node.right);
            }   
            if(node.left != null){
                queue.offer(node.left);
            }
        }
        return res;
    }
}
相关推荐
DuHz6 分钟前
论文解读:用于数据分析的极值点对称模态分解方法 (Extreme-point Symmetric Mode Decomposition,ESMD)
论文阅读·算法·信息与通信·信号处理
risc12345619 分钟前
序列化框架
数据结构
HZZD_HZZD25 分钟前
用电负荷聚类分析实战:基于`scikit-learn`的`K-Means`与`DBSCAN`双算法对比、`PCA`降维可视化与智能电表负荷画像全流程
算法·scikit-learn·kmeans
MIngYaaa52038 分钟前
2026暑期牛客多校1 2026-7-17
数据结构·算法
wabs66639 分钟前
关于图论【卡码网107.寻找存在的路线的思考】
数据结构·算法·图论
半兽先生1 小时前
大模型技术开发与应用——4.大模型提示词工程实战
人工智能·算法
wuminyu1 小时前
JUC组件逐层剥离与深度剖析
java·linux·c语言·jvm·c++·算法
hhzz2 小时前
机器学习-算法模型系列文章:07-SVM 一巴掌拍出来的超平面:SVM核函数选错,再干净的数据也救不了你
算法·机器学习·支持向量机
geovindu2 小时前
java: Gale-Shapley Algorithm
java·开发语言·后端·算法
冻柠檬飞冰走茶2 小时前
PTA基础编程题目集 7-34 通讯录的录入与显示(C语言实现)
c语言·开发语言·数据结构·算法