• LeetCode.515. 在每个树行中找最大值___逐一BFS+DFS+按层BFS


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

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

    示例1
    • 1

    在这里插入图片描述

    输入: root = [1,3,2,5,3,null,9]
    输出: [1,3,9]
    示例2:
    
    输入: root = [1,2,3]
    输出: [1,3]
     
    
    提示:
    
    二叉树的节点个数的范围是 [0,104]
    -231 <= Node.val <= 231 - 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Solution1( 逐一BFS ):

    • 首先我们采取最朴素的解法,即我们要找的是二叉树中每一层的最大值,显然我们可以使用广搜遍历二叉树,对每一层的元素进行逐个取出,并始终维护一个最大值,同时取出元素后还要将其左右非空子元素放进队列尾部。

    这里我们在进行逐一BFS时是如何辨别该元素是哪一层的呢?
    我们使用自定义类State来实现,即可维护每一个节点元素的深度。

    Code1:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    //   逐一BFS  
    class Solution {
        public List<Integer> largestValues(TreeNode root) {
            List<Integer> res = bfs(root);
            return res;
        }
    
        public List<Integer> bfs(TreeNode root){
            Queue<State> queue = new LinkedList<State>();
            if(root == null){
                return new ArrayList<Integer>();
            }
            State start = new State(root,0);
            queue.offer(start);
            List<Integer> list = new ArrayList<>();
            State max_thisDepth = new State(new TreeNode(Integer.MIN_VALUE,null,null),0);
            while(queue.size()!=0){
                TreeNode temp = queue.peek().node;
                int now_depth = queue.peek().depth;
                if(temp.left != null){
                    queue.offer(new State(temp.left,now_depth + 1));
                }
                if(temp.right != null){
                    queue.offer(new State(temp.right,now_depth + 1));
                }
                State thisState = queue.poll();
                TreeNode thisNode = thisState.node;
                if(max_thisDepth.depth == thisState.depth){
                    max_thisDepth.node.val = Math.max(max_thisDepth.node.val,thisNode.val);
                }
                else{
                    list.add(max_thisDepth.node.val);
                    max_thisDepth.node.val = thisNode.val;
                    max_thisDepth.depth = thisState.depth;
                }
            } 
            list.add(max_thisDepth.node.val);
            return list;
        }
    }
    class State{
        TreeNode node;
        int depth;
    
        public State(TreeNode node,int depth){
            this.node = node;
            this.depth = depth;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    Solution2( DFS ):

    • 按照该题的情景是应该使用广搜的,但是使用深搜同样可以解决,我们只要搭配一个哈希表进行记录每一层的最大值即可,这样在遍历二叉树的时候我们只要根据此时遍历节点的深度对哈希表进行实时更新即可。

    Code2:

    class Solution {
        Map<Integer,Integer> map = new HashMap<>();
        public List<Integer> largestValues(TreeNode root) {
            if(root == null){
                return new ArrayList<>();
            }
            dfs(root,0);
            List<Integer> res = new ArrayList<>();
            for(Map.Entry<Integer, Integer> entry : map.entrySet()){
                res.add(entry.getValue());
            }
            return res;
        }
        
        public void dfs(TreeNode root,int depth){
            if(map.containsKey(depth)){
                int value = map.get(depth);
                if(root.val > value){
                    map.put(depth,root.val);
                }
            }
            else{
                map.put(depth,root.val);
            }
    
            if(root.left!=null){
                dfs(root.left,depth+1);
            }
    
            if(root.right!=null){
                dfs(root.right,depth+1);
            }
    
            return;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    Solution3( 按层BFS ):

    • 对于方法一的广搜,我们可以对其进行优化,即不用实时的对每个节点都维护一个深度;
    • 由于我们只要求每层的最大值,我们可以按照一层一层来进行遍历,即每次我们先从队列中取出该层的所有元素,再对其进行一个遍历即可,由于我们每次取出的都是同一层的元素,因此是不需要考虑深度问题,因此可以化繁为简;

    在实现方面,我们只需要遍历时根据初始队列的长度len,从队列中取出前len个元素,即可达到取出该层的所有元素,且在取出元素的同时我们也不要忘记将取出的元素的左右非空元素再放入队列即可,这样即可达到每次队列内的元素都是同一层的元素,因此这样可以起到按层来进行搜索的效果。

    Code3:

    class Solution {
    
        public List<Integer> largestValues(TreeNode root) {
            if(root == null){
                return new ArrayList<>();
            }
            Queue<TreeNode> queue = new LinkedList<TreeNode>();
            queue.offer(root);
            List<Integer> res = new ArrayList<>();
            
            while(!queue.isEmpty()){
                int this_depth_len = queue.size();
                int max = Integer.MIN_VALUE;
                while(this_depth_len != 0){  //把该层都取出
                    TreeNode temp = queue.poll();
                    max = Math.max(temp.val,max);
                    if(temp.left != null)
                        queue.offer(temp.left);
                    if(temp.right != null)
                        queue.offer(temp.right);   
                    this_depth_len--;
                }
                res.add(max);
            }
    
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    逆向第一课---安装ADB工具,并使用夜神模拟器连接
    国庆 day 5
    【JVM经典面试题(五十二道)】
    什么是微前端
    openai sora 只能根据文本生成视频?不,TA 是通用物理世界模拟器
    授予渔,从0开始搭建一个自己想要的网页
    Day25、数据库
    VVC码率控制中的质量依赖因子QDF
    【千锋Python2205班10.20笔记-day04-接口和常见反爬(一阶段)】
    怎么设计个性时尚的班服?一起来看看莱佛士学生的设计
  • 原文地址:https://blog.csdn.net/xiangguang_fight/article/details/125476298