【算法】【优选算法】宽搜(BFS)中队列的使用

目录

一、429. N叉树的层序遍历

题目链接:429.N叉树的层序遍历

题目描述:

题目解析:

  • 层序遍历N叉树,每一层的节点是由null分开
  • 每一层节点的val值放入一个数组中,最后返回一个二维数组,每行就是对应层数据

解题思路:

  • 我们将每一层的节点放入一个队列中,每次队列出节点的时候就将这个节点的孩子节点入队
  • 因为节点数范围是包含0的,所有当根节点为null时,返回空二维数组
  • 因为出队列伴随着入队,所以要区分每层节点,在出该层队列中节点前,先求一下长度,然后出这个长度对应节点个数即可。
  • 在入队列的时候,因为使用null区分,所以要将null节点排除不入队列。

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(n)
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> ret = new ArrayList<>();
        if(root == null) return ret;//节点数为0
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int sz = queue.size();//每层节点个数

            List<Integer> tmp = new ArrayList<>();//每层节点

			//下一层节点
            for(int i = 0; i < sz; i++) {
                Node node = queue.poll();
                tmp.add(node.val);
                for(Node x : node.children) {
                    if(x != null) {
                        queue.offer(x);
                    }
                }
            }

            ret.add(tmp);
        }
        return ret;
    }
}

二、103.⼆叉树的锯⻮形层序遍历

题目链接:103.⼆叉树的锯⻮形层序遍历

题目描述:

题目解析:

  • 层序遍历二叉树,每一层节点的val值放入一个数组中,根节点为第一层,奇数层顺序放入,偶数层逆序放入,最后返回一个二维数组,每行就是对应层数据

解题思路:

  • 我们将每一层的节点放入一个队列中,每次队列出节点的时候就将这个节点的孩子节点入队
  • 因为节点数范围是包含0的,所有当根节点为null时,返回空二维数组
  • 因为出队列伴随着入队,所以要区分每层节点,在出该层队列中节点前,先求一下长度,然后出这个长度对应节点个数即可。
  • 在入队列的时候,因为使用null区分,所以要将null节点排除不入队列。
  • 使用一个变量标记一下当前的层数,最后一维数组入结果数组是,如果是偶数层数就逆序。

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(n)
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ret = new ArrayList<>();
        if(root == null) return ret;//节点数为0
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int level = 1;//层

        //入队列,出队列
        while(!queue.isEmpty()) {
            int sz = queue.size();
            List<Integer> tmp = new ArrayList<>();
            
            for(int i = 0; i < sz; i++) {
                TreeNode node = queue.poll();
                tmp.add(node.val);
                if(node.left != null) queue.offer(node.left);
                if(node.right != null) queue.offer(node.right);
            }
            //偶层数 逆序
            if(level % 2 == 0) Collections.reverse(tmp);
            ret.add(tmp);
            level++;
        }
        return ret;
    }
}

三、662.⼆叉树最⼤宽度

题目链接:662.⼆叉树最⼤宽度

题目描述:

题目解析:

  • 求二叉树中每层的长度的最大值
  • 每层的长度指:当前层第一个不是null的节点与最后一个不是null的节点之间 的 节点个数包含null节点
  • 节点数不会是0个

解题思路:

  • 我们直接将null节点填入,不仅麻烦还会超时。
  • 所以我们将二叉树看成是数组存储的,将每个节点的下标给带上,与节点构成一个键值对,放入队列中。
  • 因为我们要求长度:需要拿到每层节点第一个节点和最后一个节点的下标,那么队列不能满足需求,使用一个数组来模拟队列存储。
  • 每次在下一层节点入队前,先拿到第一个节点和最后一个节点的下标,求程度与结果的较大值。
  • 这个数组只存一层的数据,下一层我们使用一个临时数组来存储,最后赋值即可。
  • 遍历数组,将下一层不为空的节点放入临时数组。

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(n)
class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        int ret = 0;
        List<Pair<TreeNode, Integer>> queue = new ArrayList<>();//数组只存每一层节点与对应坐标
        queue.add(new Pair<>(root, 0));//根节点入队

        while(!queue.isEmpty()) {
            //数组最后元素与第一个元素的value域,求当前层的长度
            ret = Math.max(ret, queue.get(queue.size() - 1).getValue() - queue.get(0).getValue() + 1);
            //数组记录下一层节点
            List<Pair<TreeNode, Integer>> tmp = new ArrayList<>();
            for(Pair<TreeNode, Integer> node : queue) {
                if(node.getKey().left != null) tmp.add(new Pair<>(node.getKey().left, node.getValue() * 2 + 1));
                if(node.getKey().right != null) tmp.add(new Pair<>(node.getKey().right, node.getValue() * 2 + 2));
            }
            queue = tmp;
        }
        return ret;
    }
}

四、515.在每个树⾏中找最⼤值

题目链接:515.在每个树⾏中找最⼤值

题目描述:

题目解析:

  • 将二叉树中每层节点的value的最大值放入要返回的结果数组中
  • value域的值范围是int的取值范围,包含负数的

解题思路:

  • 我们将每一层的节点放入一个队列中,每次队列出节点的时候就将这个节点的孩子节点入队
  • 因为节点数范围是包含0的,所有当根节点为null时,返回空数组
  • 因为出队列伴随着入队,所以要区分每层节点,在出该层队列中节点前,先求一下长度,然后出这个长度对应节点个数即可。
  • 在出队列前,先使用一个变量赋值为int的最小值,在每次出节点前,变量更新为该节点的value与变量的更大值。
  • 在入队列的时候,要将null节点排除不入队列。

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(n)
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int sz = queue.size();
            int max = Integer.MIN_VALUE;
            for(int i = 0; i < sz; i++) {
                TreeNode node = queue.poll();
                max = Math.max(node.val, max);
                if(node.left != null) queue.offer(node.left);
                if(node.right != null) queue.offer(node.right);
            }
            ret.add(max);
        }
        return ret;
    }
}
相关推荐
xiaoshiguang32 分钟前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡4 分钟前
【C语言】判断回文
c语言·学习·算法
别NULL6 分钟前
机试题——疯长的草
数据结构·c++·算法
TT哇10 分钟前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
yuanbenshidiaos2 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习2 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA2 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo2 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc2 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
游是水里的游3 小时前
【算法day20】回溯:子集与全排列问题
算法