zoukankan      html  css  js  c++  java
  • 662_二叉树最大宽度

    662_二叉树最大宽度

    package 二叉树.BT;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.Map;
    import java.util.Queue;
    
    /**
     * https://leetcode-cn.com/problems/maximum-width-of-binary-tree/
     * 
     * @author Huangyujun
     * 
     */
    public class _662_二叉树最大宽度 {
        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;
            }
        }
    
    //层序遍历(有bug:来自于,无法应对null的中间结点)(不对的),使用map无法做到,需要像官网那样封装一个类(标记结点位置的)
        //本代码逻辑还有另外一个bug://没有把null的情况也一起计算进去【错误最根本原因】
    //    public int widthOfBinaryTree(TreeNode root) {
    //        // 根结点自己一个时,长度为0
    //        if (root == null)
    //            return 0;
    //        if (root.left == null && root.right == null)
    //            return 0;
    //        int width = 0;
    //        Queue<TreeNode> queue = new LinkedList<>();
    //        queue.offer(root);
    //        int pos = 1;
    //        int left = 0;
    //        int right = 0;
    //        int levelSize = 1;        
    //        //为啥不能使用map了(如果是这样,进入当前层时,找不着当前层的第一个结点)
    //        Map<TreeNode, Integer> map = new HashMap<TreeNode, Integer>();
    //        map.put(root, pos);
    //        while (!queue.isEmpty()) {
    //            // 拿到当前结点
    //            TreeNode node = queue.poll();            
    //            levelSize--;
    //            // 该层出现的最左位置
    //            if (node.left != null) {
    //                queue.offer(node.left);
    ////                left++;// 左边位置往左移动
    ////                添加最左的位置(位置信息等于 node 的 2 倍)
    //                map.put(node.left, map.get(node) * 2);
    //            }
    //            // 该层出现的最右位置
    //            if (node.right != null) {
    //                queue.offer(node.right);
    ////                right++;
    //                map.put(node.right, map.get(node) * 2);
    //            }
    //            if(levelSize == 0) {
    //                //即将进入下一层
    //                //获取到当前层的最左边,最右边
    //                for(int i = 0; i < map.size(); i++) {
    ////                    left = Math.min(left, map.get)
    //                }
    //                levelSize = queue.size();
    //            }
    //        }
    //
    //        return width;
    //    }
    
        /**
         * 核心思路是位置化(坐标化结点~ 下一个结点(咱只需拿到最左的那个结点,当进入下一层便知道了)位置 i = 2 * i)
         * (用 键值对标记【结点, 位置】,而不是官网给的包装成一个类(含有深度和位置的结点))
         * 
         * 思路是:遍历到结点(就给该结点标注一个位置),该位置信息直接存放到结点的val中 而结点位置:等于 2 * i (i 是 上一层(父元素位置))
         * 咱需要定义一个变量来判断结点进入下一层了(depth),从而更新left(最左位置) 然后 (遍历到的当前位置 - 最左位置) 不断更新找到最大位置
         * 
         * @author Huangyujun
         *
         */
        class AnnotatedNode {
            TreeNode node;
            int depth, pos;
    
            AnnotatedNode(TreeNode n, int d, int p) {
                node = n;
                depth = d;
                pos = p;
    
            }
    
            // 突破点在于标记最左结点位置
            // 通过公式: 下一层的结点位置 2 * i (i 是上一层的)
            public int widthOfBinaryTree(TreeNode root) {
                Queue<AnnotatedNode> queue = new LinkedList();
                queue.add(new AnnotatedNode(root, 0, 0));
                int curDepth = 0, left = 0, ans = 0;
                while (!queue.isEmpty()) {
                    AnnotatedNode a = queue.poll();
                    if (a.node != null) {//很巧妙的把null的情况也一起计算进去
                        queue.add(new AnnotatedNode(a.node.left, a.depth + 1, a.pos * 2));
                        queue.add(new AnnotatedNode(a.node.right, a.depth + 1, a.pos * 2 + 1));
                        if (curDepth != a.depth) {
                            curDepth = a.depth;
                            left = a.pos;
                        }
                        ans = Math.max(ans, a.pos - left + 1);
                    }
                }
                return ans;
            }
        }
    }

    本文来自博客园,作者:一乐乐,转载请注明原文链接:https://www.cnblogs.com/shan333/p/15709262.html

  • 相关阅读:
    多线程-工作组模式
    iOS端架构、基本组成与使用说明
    iOS,Core Animation--负责视图的复合功能
    Container Views
    IOS UIView 01-View开始深入 绘制像素到屏幕上
    View Programming Guide for iOS
    UI绘图与信息、样式
    iOS绘图框架CoreGraphics分析
    iOS开发系列--打造自己的“美图秀秀”
    Array与NSArray关系
  • 原文地址:https://www.cnblogs.com/shan333/p/15709262.html
Copyright © 2011-2022 走看看