算法---队列+宽搜

1.N叉树的层序遍历

题目链接:429. N 叉树的层序遍历 - 力扣(LeetCode)

题目解析:返回N叉树层序遍历的结果,层序遍历就是从上到下,一层一层得遍历,每一层的遍历从左往右开始

算法讲解:队列

首先创建一个队列,此时开始层序遍历N叉树,一层一层得遍历,将每一层遍历的结果存储到队列中,在进行下一层的遍历时,要将上一层遍历的结果记录到结果集中,也就是要对存储到队列中的节点进行出队列的操作,每次将一个节点出队列之后,就要将出队列的节点的孩子节点存储到队列中

此时可能队列中会存储到了N叉树中不同层次的节点,因为要区分不同层的节点,所以对上一层队列中存储的节点进行出队列操作时,就要对上一层入队列的节点的个数进行记录

代码实现:

java 复制代码
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        Queue<Node> q = new LinkedList<>();
        List<List<Integer>> ret = new ArrayList<>();
        if(root==null) return ret;
        q.offer(root);
        while(!q.isEmpty()){
            int sz = q.size();
            List<Integer> tmp = new ArrayList<>();
            for(int i=0;i<sz;i++){
                Node head = q.poll();
                tmp.add(head.val);
                //将出队列节点的孩子节点入队列
                for(Node child:head.children){
                    if(child!=null){
                        q.offer(child);
                    }
                }
            }
            ret.add(tmp);
        }
        return ret;
    }
}

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

题目链接:103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode)

题目解析:返回二叉树进行锯齿形遍历的结果

算法讲解:队列+宽搜

这道题的解题思路和上一题的思路一模一样,只不过在记录奇数层的结果时,要先对该层的遍历结果逆序之后,再将该该层的遍历结果加入到最终的结果中

此时可以创建一个boolean类型的变量或者一个int类型的变量来判断该层是偶数层还是奇数层

代码实现:

java 复制代码
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        Queue<TreeNode> q = new LinkedList<>();
        List<List<Integer>> ret = new LinkedList<>();
        if(root==null) return ret;
        q.offer(root);
        int flag=1;
        while(!q.isEmpty()){
            //sz是某一层的节点个数
            int sz=q.size();
            List<Integer> tmp = new LinkedList<>();
            for(int i=0;i<sz;i++){
                TreeNode top = q.poll();
                if(top.left!=null) q.offer(top.left);
                if(top.right!=null) q.offer(top.right);
                tmp.add(top.val);
            }
            if(flag%2==0){
                Collections.reverse(tmp);
            }
            ret.add(tmp);
            flag++;
        }
        return ret;
    }
}

3.二叉树的最大宽度

题目链接:662. 二叉树最大宽度 - 力扣(LeetCode)

题目解析:返回该二叉树的最大宽度

算法讲解:队列

这道题的难点就是在要考虑null节点,如果某一层的开始节点和结束节点中有空节点,我们在计算宽度时也要将空节点考虑进去

此时可以根据二叉树的另一种表达方法来解决问题,我们知道二叉树是可以用数组来表示的,假设一个父节点在数组的下标为i(假设根节点的下标为1),那么该根节点的左孩子结点对应到数字的下标就为2*i,该根节点的右孩子节点对应到数组的下标就为2*i+1

如果根节点的下标为0的话,那么此时左孩子节点对应到数组的下标就是2*i+1,右孩子对应到数组的小标就是2*i+2

则此时我们就可以通过对二叉树的节点进行编号,此时二叉树中某一层的宽度就是该层的开始节点的编号减去该层最后一个节点的编号+1

则此时可以创建一个Queue<Pair<TreeNode,Integer>>的队列,此时依旧是前面两道题的思路,先将根节点放进队列中,然后依次对节点进行出队列,每一个节点出队列后,要将该节点的左右孩子节点入队列

此时就是有一个不同点,就是在遍历二叉树的某一层时,要记得记录该层的第一个节点的编号和该层最后一个节点的编号

代码实现:

java 复制代码
class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        Queue<Pair<TreeNode,Integer>> q = new LinkedList<>();
        q.offer(new Pair<>(root,1));
        int ret=1;
        while(!q.isEmpty()){
            int sz=q.size();
            int left = 0;//left记录该层第一个节点的编号
            int right = 0;//right记录该层最后一个节点的编号
            for(int i=0;i<sz;i++){
                Pair<TreeNode,Integer> pair = q.poll();
                TreeNode node = pair.getKey();
                int index = pair.getValue();
                if(i==0) left=index;//此时index是该层第一个节点的编号
                if(i==sz-1) right=index;//此时index是该层最后一个节点的编号
                if(node.left!=null) q.offer(new Pair<>(node.left,index*2));
                if(node.right!=null) q.offer(new Pair<>(node.right,index*2+1));
            }
            ret=Math.max(ret,right-left+1);
        }
        return ret;
    }
}

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

题目链接:515. 在每个树行中找最大值 - 力扣(LeetCode)

算法讲解:队列+层序遍历

其实这道题的解题思路几乎和前面的题目一模一样,不过就是在层序遍历的过程中要创建一个变量来记录每一层的最大值

代码实现:

java 复制代码
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> ret = new LinkedList<>();
        Queue<TreeNode> q = new LinkedList<>();
        if(root==null) return ret;
        q.offer(root);
        while(!q.isEmpty()){
            int sz = q.size();
            int max=Integer.MIN_VALUE;
            for(int i=0;i<sz;i++){
                TreeNode node = q.poll();
                int tmp = node.val;
                max=Math.max(max,tmp);
                if(node.left!=null) q.offer(node.left);
                if(node.right!=null) q.offer(node.right);
            }
            ret.add(max);
        }
        return ret;
    }
}
相关推荐
启观川4 小时前
数据结构与算法 -第 3 章 常用算法-动态规划
数据结构·笔记·python·算法
码爸4 小时前
排序算法介绍
python·算法·排序算法
动词ing5 小时前
【题目练习】算法 组合总和||
算法
longlongzihan5 小时前
链表找环:Floyd 判圈算法(LeetCode 141 & 142 )
c++·算法·leetcode·链表
专业程序开发源5 小时前
flask家电故障预测系统92491-计算机课程设计/毕业设计
vscode·python·sql·算法·flask·课程设计
Logic1015 小时前
C语言/数据结构欧几里得算法题解:长方形切割最大正方形——贪心划分计数
c语言·数据结构·算法·贪心算法·时间复杂度·空间复杂度·欧几里得算法
yi0116 小时前
LeetCode 643. 子数组最大平均数 I|从暴力枚举到滑动窗口
人工智能·笔记·python·算法·leetcode·滑动窗口
极光通讯6 小时前
服务器内存来料检验(IQC)实操:批次追溯、外观判定与上机验证
java·服务器·算法
淡海水7 小时前
02-04-原理篇-GC Roots与对象图遍历
算法·unity·c#·图·gc·遍历·roots
ClickHouseDB7 小时前
ClickHouse 大规模 OpenTelemetry 数据接入架构的可靠性演进
算法