优选算法-队列+宽搜

算法原理

队列基本知识

1.是一个接口底层是通过链表实现的

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表(从队尾进,从对头处)

2.常见的方法

boolean offer(E e)入队列

E poll() 出队列

peek()获取对头元素

int size()有效元素个数

boolean isEmpty()判读是否为空

搜索类算法

深搜(dfs)vs宽搜(bfs)

宽搜是广度优先遍历 深搜是深度优先遍历(我们在图的数据结构中了解过)

这篇文章主要是利用队列先进先出的特性结合搜索类算法中比较重要的宽搜(bfs)来解决树相关的问题

题目解析

1.N 叉树的层序遍历

题目描述

给定一个N叉树,返回其节点值的层序遍历(即从左到右,逐层遍历)

树的序列化输入时用层序遍历,每个子节点都由null值分割

算法原理

解法:利用队列实现bfs

queue:当队列不空时,拿出队头元素,把队头孩子入队

那么我们如何判断元素在一层? 只需要在入队之前,先统计队列中的元素个数,出队列时只要出相应的个数即可

代码实现

java 复制代码
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> ret=new ArrayList<>();
        if(root==null) return ret;
        Queue<Node> q=new LinkedList<>();
        q.add(root);
        while(!q.isEmpty()){
            int sz=q.size();
            List<Integer> tmp=new ArrayList<>();
            for(int i=0;i<sz;i++){
                Node t=q.poll();
                for(Node child:t.children){
                    q.add(child);
                }
                tmp.add(t.val);
            }
            ret.add(tmp);
        }
        return ret;
    }
}

2.二叉树的锯齿形层序遍历

题目描述

给你二叉树的根节点root,返回其根节点值的锯齿形层序遍历(即先从左往右,再从右向左,以此类推,层与层之间交替进行)

算法原理

解法:利用队列先进先出的特价来完成层序遍历(和上一道题类似,我们只需要增加一个标记位,让偶数行的信心逆序即可 用boolean/int都可以)

代码实现

java 复制代码
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ret=new ArrayList<>();
        if(root==null) return ret;
        Queue<TreeNode> q=new LinkedList<>();
        q.add(root);
        int s=1;
        while(!q.isEmpty()){
            int sz=q.size();
            List<Integer> tmp=new ArrayList<>();
            for(int i=0;i<sz;i++){
                TreeNode t=q.poll();
                tmp.add(t.val);
                if(t.left!=null){
                    q.add(t.left);
                }
                if(t.right!=null){
                    q.add(t.right);
                }
            }
            if(s%2==0){
                Collections.reverse(tmp);
            }
            ret.add(tmp);
            s++;
        }
        return ret;
    }
}

3.二叉树最大宽度

题目描述

给你一颗二叉树的根节点root,返回数的最大宽度

树的最大宽度是所有层中最大的宽度

每一层的宽度被定义为该层最左和最右的非空节点(即两个端点)之间的长度,将这个二叉树视作与满二叉树结构相同,两端点之间会出现一些延伸到这一层的null节点,这些null节点也计入长度

算法原理

解法一:硬来(这是错误的,因为空间复杂度和时间复杂度都超了)

解法二:利用数组存储二叉树的方式,给节点编号

这里我们可以利用queue<pair<TreeNode,int>> 宽度计算:队头-队尾+1

可以直接搞一个数组来模拟数列

细节:

下标有可能溢出

当我们相减之后,即使溢出,结果也是正确的(但计算本质上是算两者之间的距离,距离是不会溢出的,距离是正确的 题目上说不会超过32位,说明不会超过一圈)

代码实现

java 复制代码
class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        List<Pair<TreeNode,Integer>> q=new ArrayList<>();
        q.add(new Pair<TreeNode,Integer>(root,1));
        int ret=0;
        while(!q.isEmpty()){
            Pair<TreeNode,Integer> t1=q.get(0);
            Pair<TreeNode,Integer> t2=q.get(q.size()-1);
            ret=Math.max(ret,t2.getValue()-t1.getValue()+1);
            List<Pair<TreeNode,Integer>> tmp=new ArrayList<>();
            for(Pair<TreeNode,Integer> t:q){
                TreeNode node =t.getKey();
                int index=t.getValue(); 
                if(node.left!=null){
                  tmp.add(new Pair<TreeNode,Integer>(node.left,index*2));
                }
                if(node.right!=null){
                  tmp.add(new Pair<TreeNode,Integer>(node.right,index*2+1));
                }
            }
            q=tmp;
        }
        return ret;
    }
}

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

题目描述

给定一棵二叉树的根节点root,请找出该二叉树中每一层的最大值

算法原理

利用层序遍历,统计出每一层的最大值

代码实现

java 复制代码
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> ret=new ArrayList<>();
        if(root==null) return ret;
        Queue<TreeNode> q=new LinkedList<>();
        q.add(root);
        while(!q.isEmpty()){
            int sz=q.size();
            int tmp=Integer.MIN_VALUE;
            for(int i=0;i<sz;i++){
                TreeNode t=q.poll();
                tmp=Math.max(t.val,tmp);
                if(t.left!=null){
                    q.add(t.left);
                }
                if(t.right!=null){
                    q.add(t.right);
                }
            }
            ret.add(tmp);
        }
        return ret;
        
    }
}
相关推荐
枫叶林FYL7 分钟前
【群体智能集群控制工程实践】第3章 一致性协同算法
算法
禹凕26 分钟前
滑动窗口算法实战指南
python·算法
DisonTangor32 分钟前
【腾讯混元雪耻归来】 Hy4 preview:770B 参数 MoE 旗舰模型,1M 上下文全面开源
人工智能·算法·开源·aigc·腾讯云·腾讯云ai代码助手
明月_清风2 小时前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
渡我白衣2 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
hetao17338372 小时前
2026-09-01~09-04 hetao1733837 的刷题记录
c++·算法
Evand J2 小时前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动
血小板要健康3 小时前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a187927218313 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
HugoStudio_SWAN5 小时前
洛谷 P1420 / P1179 / B4262 最长连号、数字统计与词频统计——统计的三种面孔
c++·学习·程序人生·算法