11道精选经典LeetCode例题让你彻底搞懂二叉树的广度优先遍历

Posted 温文艾尔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11道精选经典LeetCode例题让你彻底搞懂二叉树的广度优先遍历相关的知识,希望对你有一定的参考价值。

相见即是有缘,如果对你有帮助,给博主一个免费的点赞以示鼓励把QAQ

广度优先搜索是遍历二叉树的一种基本方式,也就是层序遍历一个二叉树。从左到右一层一层的去遍历二叉树,对此我们需要借助数据结构队列来完成,因为队列先进先出的特点符合我们遍历的要求,也会成为我们解题的关键,今天我们用11道经典LeetCode算法题认识二叉树的广度优先搜索


有上述二叉树,我们利用队列Queue对其进行层序遍历
先使6提前进入队列
6进队列

第1轮遍历,6出队列,6的两个子节点 4,7进入队列


第2轮遍历,4出队列,4的1,3节点进队列,7出队列,7的5,8节点进队列


第3轮遍历 1,3,5,8为叶子结点,依次退出队列

下面我们结合11道题目对层序遍历进行理解

1.二叉树的层序遍历|

题目链接:

    public List<List<Integer>> resList = new ArrayList<>();
    public List<List<Integer>> levelOrder(TreeNode root) 
//        checkFun02(root,resList);
        checkFun01(root,0);
        return resList;
    

//BFS,广度优先遍历
    private void checkFun02(TreeNode root, List<List<Integer>> resList) 
        if (root==null)
            return;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);

        while (!queue.isEmpty())
            int len = queue.size();
            List<Integer> list = new ArrayList<>();

            while (len>0)
                TreeNode poll = queue.poll();
                list.add(poll.val);
                if (poll.left!=null) queue.offer(poll.left);
                if (poll.right!=null) queue.offer(poll.right);
                len--;
            
            resList.add(list);
        
    

    //DFS 深度优先遍历
    private void checkFun01(TreeNode root, int dep) 
        if (root==null)
            return;
        
        dep++;
        while (resList.size()<dep)
            List<Integer> list = new ArrayList<>();
            resList.add(list);
        
        resList.get(dep-1).add(root.val);
        if (root.left!=null) checkFun01(root.left,dep);
        if (root.right!=null) checkFun01(root.right,dep);
    

2.二叉树的层序遍历||

题目链接

    public List<List<Integer>> levelOrderBottom(TreeNode root) 
        List<List<Integer>> resList = new ArrayList<>();
        if (root==null)
            return resList;
        

        Queue<TreeNode> queue = new LinkedList();
        queue.add(root);
        while (!queue.isEmpty())
            int len = queue.size();
            List<Integer> list = new ArrayList<>();
            while (len>0)
                TreeNode poll = queue.poll();
                list.add(poll.val);
                if (poll.left!=null) queue.offer(poll.left);
                if (poll.right!=null) queue.offer(poll.right);
                len--;
            
            resList.add(list);
        
        Collections.reverse(resList);
        return resList;
    

3.二叉树的右视图

题目链接

注意右视图看到的元素指的不单单是右子树的元素,而是每一层最右侧的元素,这个元素也有可能出现在左子树,所以需要将每一层的最后一个元素加入集合

    public List<Integer> rightSideView(TreeNode root) 
        List<Integer> list = new ArrayList<>();
        if (root==null)
            return list;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty())
            int len = queue.size();
            while (len>0)
                TreeNode poll = queue.poll();
                if (len==1)
                    list.add(poll.val);
                
                if (poll.left!=null) queue.offer(poll.left);
                if (poll.right!=null) queue.offer(poll.right);
                len--;
            
        
        return list;
    

4.二叉树的层平均值

题目链接

利用层序遍历,记录每一层的数字并计算平均值即可

    public List<Double> averageOfLevels(TreeNode root) 
        List<Double> list = new ArrayList<>();
        if (root==null)
            return list;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty())
            double sum = 0;
            int len = queue.size();
            int temp=len;
            while (len>0)
                TreeNode poll = queue.poll();
                sum+=poll.val;
                len--;
                if (poll.left!=null) queue.offer(poll.left);
                if (poll.right!=null) queue.offer(poll.right);
            
            list.add(sum/temp);
        
        return list;
    

5.n叉树的层数遍历

题目链接

    public List<List<Integer>> levelOrder(Node root) 
        List<List<Integer>> resList = new ArrayList<>();
        if (root==null)
            return resList;
        
        Deque<Node> queue = new LinkedList<>();
        queue.offerLast(root);
        while (!queue.isEmpty())
            int len = queue.size();
            List<Integer> list = new ArrayList<>();

            for (int i=0;i<len;i++)
                Node poll = queue.pollFirst();
                list.add(poll.val);
                List<Node> children = poll.children;
                if (children==null||children.size()==0)
                    continue;
                
                for (Node child : children) 
                    if (child!=null)
                        queue.offerLast(child);
                    
                
            
            resList.add(list);
        
        return resList;
    

6.在每个树行找最大值

题目链接

    public List<Integer> largestValues(TreeNode root) 
        List<Integer> list = new ArrayList<>();
        if (root==null)
            return list;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty())
            int len = queue.size();
            int max = Integer.MIN_VALUE;
            for (int i=0;i<len;i++)
                TreeNode poll = queue.poll();
                if (poll.val>max)
                    max = poll.val;
                
                if (poll.left!=null) queue.offer(poll.left);
                if (poll.right!=null) queue.offer(poll.right);
            
            list.add(max);
        
        return list;
    

7.填充每个节点的下一个右侧节点指针

题目链接

        Queue<Node> queue = new LinkedList<>();
        if (root==null)
            return null;
        
        queue.offer(root);
        while (!queue.isEmpty())
            int len = queue.size();
            Node nodePre = null;
            Node node;
            for (int i=0;i<len;i++)
                if (i==0)
                    nodePre = queue.poll();
                    node = nodePre;
                else 
                    node = queue.poll();
                    nodePre.next = node;
                    nodePre = nodePre.next;
                
                if (node.left!=null) queue.offer(node.left);
                if (node.right!=null) queue.offer(node.right);
            
        
        return root;

8.填充每个节点的下一个右侧节点指针||

题目链接

这道题目说是二叉树,但第7题题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑一样的味道

    public Node connect2(Node root) 
        Queue<Node> queue = new LinkedList<>();
        if (root==null)
            return null;
        
        queue.offer(root);
        while (!queue.isEmpty())
            int len = queue.size();
            //处理第一个节点
            Node top = queue.poll();
            if (top.left!=null) queue.offer(top.left);
            if (top.right!=null) queue.offer(top.right);
            for (int i=1;i<len;i++)
                Node poll = queue.poll();
                if (poll.left!=null) queue.offer(poll.left);
                if (poll.right!=null) queue.offer(poll.right);
                top.next = poll;
                top = top.next;
            
        
        return root;
    

9.二叉树的最大深度

题目链接

广度优先搜索解法:

    public int maxDepth(TreeNode root) 
        int max = 0;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty())
            int len = queue.size();
            for (int i=0;i<len;i++)
                TreeNode poll = queue.poll();
                if (poll.left!=null) queue.offer(poll.left);
                if (poll.right!=null) queue.offer(poll.right);
            
            max++;
        
        return maxLeetCode刷题日记精选例题(代码+链接)

LeetCode刷题日记精选例题-双指针经典问题总结

刷题那些事Leetcode精选二叉树例题+解析

如何彻底搞懂 Java 数据结构?|CSDN 博文精选

从原理到实践彻底搞懂 Java 日志系统,再也不迷茫了!

LeetCode经典题分类(链表 - 树 - 图)精选 - JavaScript - ES6 - 技巧总结