队列+宽搜

N 叉树的层序遍历

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

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

思路:

我们首先判断根节点是否为空,若为空则直接返回空列表。

否则,我们创建一个队列 q,初始时将根节点加入队列。

当队列不为空时,我们循环以下操作:

  1. 创建一个空列表 list,用于存放当前层的节点值。
  2. 对于队列中的每个节点,将其值加入 list中,并将其子节点加入队列。
  3. 将 list加入结果列表 ret。

最后返回结果列表 ret。

java 复制代码
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> ret = new ArrayList<>();
        if(root == null) {
            return ret;
        }
        //创建队列 先进先出特性
        Queue<Node> queue = new ArrayDeque<>();
        //将root放进队列中
        queue.offer(root);
        while(!queue.isEmpty()) {
            //计算此时queue里面的大小
            int n = queue.size();
            //用于存储每层节点数量
            List<Integer> list = new ArrayList<>();
            while(n != 0) {
                Node cur = queue.poll();
                list.add(cur.val);
                //将结点的孩子带进队列中
                for(Node x :cur.children) {
                    queue.offer(x);
                }
                n--;
            }
            //添加结果
            ret.add(list);
        }
        return ret;
    }
}

二叉树的锯齿形层序遍历

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

思路:

为了实现锯齿形层序遍历,需要在层序遍历的基础上增加一个标志位 i,用于标记当前层的层数。如果 i 为奇数,则当前层的节点值按照从左到右的顺序存入结果数组 ret中;如果 i为偶数,则当前层的节点值按照从右到左的顺序存入结果数组 ret中。

右到左的顺序:借助容器Collections的reverse函数反转

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 ArrayDeque<>();
        q.offer(root);
        int i = 1;
        while(!q.isEmpty()) {
            int n = q.size();
            ArrayList<Integer> list = new ArrayList<>();
            while(n-- != 0) {
                TreeNode cur = q.poll();
                list.add(cur.val);
                if(cur.left != null) {
                    q.offer(cur.left);
                }
                if(cur.right != null) {
                    q.offer(cur.right);
                }
            }
            if(i++ % 2 == 0) Collections.reverse(list);
            ret.add(list);
        }
        return ret;
    }
}

二叉树最大宽度

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

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

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

题目数据保证答案将会在 32 位 带符号整数范围内。

此题求二叉树所有层的最大宽度,比较直观的方法是求出每一层的宽度,然后求出最大值。求每一层的宽度时,因为两端点间的 null 节点也需要计入宽度,因此可以对节点进行编号。

一个编号为 index 的左子节点的编号记为 2×index,右子节点的编号记为 2×index+1,计算每层宽度时,用每层节点的最大编号减去最小编号再加 1 即为宽度。


那么我们通过编号就可以计算同层中两个节点直接的距离了。
对于编号的存储,使用JDK内置的Pair对象
具体细节看代码:

java 复制代码
class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        //存储pair 第一个值为node ,第二个值为它的编号 
        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);
           //创建新的q 保证每次记录的都是一层结果
           List<Pair<TreeNode,Integer>> tmp =  new ArrayList<>();
           for(Pair<TreeNode,Integer> t : q) {
                TreeNode cur = t.getKey();
                if(cur.left != null) {
                    tmp.add(new Pair<TreeNode,Integer>(cur.left,t.getValue()*2));
                }
                if(cur.right != null) {
                    tmp.add(new Pair<TreeNode,Integer>(cur.right,t.getValue()*2 + 1));
                }

           }
           //更新结果 让q 等于自己的下一层
           q = tmp;

        }
        return ret;
    }
}

在每个树行中找最大值

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

使用 BFS 进行层序遍历,单次 BFS 逻辑将整一层的元素进行出队,维护当前层的最大值,并将最大值加入答案。

java 复制代码
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;
        Queue<TreeNode> q = new ArrayDeque<>();
        q.offer(root);
        int max = Integer.MIN_VALUE;
        while(!q.isEmpty()) {
            int n = q.size();
            while(n-- != 0) {
                TreeNode cur = q.poll();
                max = Math.max(max,cur.val);
                if(cur.left != null) q.offer(cur.left);
                if(cur.right != null) q.offer(cur.right);
            }
            ret.add(max);
            max = Integer.MIN_VALUE;
        }
        return ret;
    }
}
相关推荐
cloud___fly几秒前
力扣hot100——矩阵
算法·leetcode·矩阵
DogDaoDao2 分钟前
leetcode 面试经典 150 题:长度最小的子数组
算法·leetcode·面试·双指针·滑动窗口·数据结构与算法·子数组
付宇轩3 分钟前
leetcode 3195.包含所有1的最小矩形面积I
java·算法·leetcode
sjsjs116 分钟前
【多维 DP】力扣2400. 恰好移动 k 步到达某一位置的方法数目
算法·leetcode·职场和发展
陌然。。12 分钟前
【347. 前 K 个高频元素 中等】
数据结构·c++·笔记·算法·leetcode
阳光的错12 分钟前
C语言栈和队列
c语言·算法··队列
怀念无所不能的你13 分钟前
洛谷P1918 保龄球(c嘎嘎)
算法
code monkey.20 分钟前
【排序算法】——选择排序
c++·算法·排序算法
CodeCraft Studio1 小时前
DHTMLX Scheduler 7.2全新发布:增强了重复事件的编辑、修改了实时更新等
算法·ui·甘特图
南嘉5601 小时前
商用密码标准实现
java·数据结构·算法