二叉树的垂直顺序遍历中具有相同垂直高度的相同级别元素的问题

Posted

技术标签:

【中文标题】二叉树的垂直顺序遍历中具有相同垂直高度的相同级别元素的问题【英文标题】:Problem with elements at same level with same vertical height in Vertical Order Traversal of a Binary Tree 【发布时间】:2020-08-10 23:11:14 【问题描述】:

伪代码

    创建了一个类来保存节点及其水平高度

    使用 BFS,因此创建一个队列并插入第一个水平高度为 0 的节点

    从队列中弹出元素,如果地图中不存在水平高度,则为其创建一个条目

    获取水平高度的ArrayList并将节点的值添加到其中

    检查左右孩子,如果不为空则将它们添加到队列中

    class Solution 
    
      class Node
        TreeNode key;
        int h;
        Node(TreeNode key,int h)
            this.key=key;
            this.h=h;
          
       
    
    public List<List<Integer>> verticalTraversal(TreeNode root) 
        if(root==null)
            return null;
        TreeMap<Integer, ArrayList<Integer>> map = new TreeMap<>();
        Queue<Node> q=new LinkedList<>();
        q.add(new Node(root,0));
    
        while(!q.isEmpty())
            Node tmp=q.poll();
            if(!map.containsKey(tmp.h))
                map.put(tmp.h,new ArrayList<Integer>());
            map.get(tmp.h).add(tmp.key.val);           
            if(tmp.key.left!=null)
                q.add(new Node(tmp.key.left,tmp.h-1));
            if(tmp.key.right!=null)
                q.add(new Node(tmp.key.right,tmp.h+1));
        
    
        List<List<Integer>> ans=new ArrayList<>();
        for(ArrayList<Integer> al:map.values())
            ans.add(al);
        
        return ans;
    
    

问题 输入失败

输入: [0,2,1,3,null,null,null,4,5,null,7,6,null,10,8,11,9]

【问题讨论】:

if(tmp.key.left!=null) q.add(new Node(tmp.key.left,tmp.h-1)); 不应该是tmp.h+1 吗? 不,它就像一个数字线。如果一个节点在 n 高度,那么左边是 n-1,右边是 n+1 那不是水平高度吗?想象一下垂直线与水平线。垂直高也是树中节点的高 - 从下到上。而水平高度是节点从左到右的位置,就像您的任务一样。 是的,是诺伯特。感谢您的澄清,我已经更新了问题 【参考方案1】:

首先,您可能在谈论水平高度而不是您的输出所建议的垂直高度。您得到的输出似乎是正确的,因为在进行 BFS 遍历时,您首先查看左侧元素,然后在水平高度上独立地从上到下查看右侧。树级别的左节点总是会被更快地处理(因此它的子节点也将被更快地添加到队列中),因此在级别 3(从 0 开始从上到下索引)具有值 7 的节点将更快地添加到队列中进行处理然后节点的值为 6。因此在我看来输出似乎是正确的,你能告诉我们为什么你期望不同的输出吗?

根据你的任务链接中的这句话(https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree/): “如果两个节点的位置相同,那么先上报的节点的值是较小的那个。”

您似乎需要在结果列表中对子列表进行排序。您可以使用以下代码做到这一点:

sortedResult = resultList.stream()
    .map(list -> list.stream().sorted().collect(Collectors.toList()))
    .collect(Collectors.toList());

【讨论】:

是的,这就是我想要做的。但是我尝试在 leetcode 上提交,但它不接受我的代码。这是链接:leetcode.com/problems/vertical-order-traversal-of-a-binary-tree 您的预期输出不应该在预期输出列表的最右边包含值为 1 的节点吗? 问题是您正在为 BFS 方法获得正确的输出,但测试验证您的算法期望对相同的水平值节点进行排序,我将对我的答案进行编辑。

以上是关于二叉树的垂直顺序遍历中具有相同垂直高度的相同级别元素的问题的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的垂直顺序遍历

二叉树父级与顺序优先输出相同

二叉树垂直遍历 · Binary Tree Vertical Order Traversal

java 314.二叉树垂直顺序遍历(#)。java

java 314.二叉树垂直顺序遍历(#)。java

java 314.二叉树垂直顺序遍历(#)。java