【问题标题】:Top view of a Binary tree in pythonpython中二叉树的顶视图
【发布时间】:2021-09-12 05:07:18
【问题描述】:

我正在尝试解决 geeksforgeeks.com 上的 top view of the binary tree 问题

下面给出的是二叉树。任务是打印二叉树的顶视图。二叉树的顶视图是从顶部查看树时可见的节点集。对于下面给出的树

      1
   /    \
  2      3
 / \    / \
4   5  6   7

顶视图将为:4 2 1 3 7

注意:将节点从leftmost节点返回到rightmost节点。

谁能告诉我我的代码哪里出错了?它适用于我尝试过的大多数案例,而对于一个太长而无法试运行的案例则失败了。

class Solution:
  
    #Function to return a list of nodes visible from the top view 
    #from left to right in Binary Tree.

    def topView(self,root):
        left_ans = []
        def left_view(root,level) :
            if not root : return 
            if level > len(left_ans) : left_ans.append(root.data)
            left_view(root.left,level+1)
            left_view(root.right,level-1)
        
        right_ans = []
        def right_view(root,level) :
            if not root: return
            if level > len(right_ans) : right_ans.append(root.data)
            right_view(root.right,level+1)
            right_view(root.left,level-1)
        
        left_view(root,level = 1)
        right_view(root,level =1)
        
        return left_ans[::-1]+right_ans[1:]

失败的树:

               __________________23______________________
              /                                          \
          __17__                        _________________65__________________ 
         /      \                      /                                     \
      __9__      19            ______38_______                             __69__
     /     \    /  \          /               \                           /      \
    7      10  18  21       37       __________43__________              67      74
   / \       \    /  \     /        /                      \            /  \    /
  1   8      14  20  22  33       39                _______53_______   66  68  70
   \        /  \        /        /  \              /                \            \
    4      13  16   __29_      35   40           51                _62_          71 
   / \    /   /    /     \    /  \    \         /  \              /    \           \
  3   5  11  15  27      32  34  36   41      45   52          __58__  63          72 
 /     \   \    /  \    /               \    /  \             /      \   \           \
2       6  12  24  28  30               42  44   47          57      61  64          73
                 \       \                      /  \        /       /
                 26      31                    46  49      55      60 
                /                                 /  \    /  \    /
               25                                48  50  54  56  59

预期输出:

2 1 7 9 17 23 65 69 74 63 64

我的代码输出(错误):

2 1 7 9 17 23 65 69 74 72 73

【问题讨论】:

    标签: python-3.x tree binary-tree


    【解决方案1】:

    您的算法假定首先访问最高节点,但情况并非总是如此。这是一个最小的例子:

               7
              / \
             1   11
              \ /
               2 (10)
              / \
             9   6
            /   /
           8   5 
              /
             4
            /
           3
    

    请注意,从根部弹出的两个分支,向下交叉两层(11 的左孩子是 10,而 1 的右孩子是 2)。由于您首先访问左子树,因此您将注册 3 从顶部可见。当您稍后遍历另一条路径时,它不会得到更新。

    一种解决方案是保持找到节点的深度。如果稍后在相同的垂直偏移 (level) 处找到另一个候选者,则可以比较这两个节点的深度并决定哪个在另一个之上。

    第二个问题是挑战提到解决方案应该“将节点从最左边的节点返回到最右边的节点。”。这是一个有点模棱两可的说法,但它似乎意味着当两个节点处于相同的高度和相同的垂直偏移时,应该优先考虑通过左先遍历找到的节点。但是在right_view 中,您使用了相反的顺序:只需更改递归调用的顺序即可。

    这是使用 depth 的概念和固定递归调用顺序更新的函数:

    def topView(self,root):
        left_ans = []
        left_depth = []
        def left_view(root,level,depth) :
            if not root:
                return 
            if level >= 0:
                if level >= len(left_ans): 
                    left_ans.append(root.data)
                    left_depth.append(depth)
                elif depth < left_depth[level]:
                    left_ans[level] = root.data
                    left_depth[level] = depth
            left_view(root.left,level+1,depth+1)
            left_view(root.right,level-1,depth+1)
        
        right_ans = []
        right_depth = []
        def right_view(root,level,depth):
            if not root:
                return
            if level >= 0:
                if level >= len(right_ans): 
                    right_ans.append(root.data)
                    right_depth.append(depth)
                elif depth < right_depth[level]:
                    right_ans[level] = root.data
                    right_depth[level] = depth
            right_view(root.left,level-1,depth+1)
            right_view(root.right,level+1,depth+1)
        
        left_view(root,0,0)
        right_view(root,0,0)
    
        return left_ans[::-1]+right_ans[1:]
    

    【讨论】:

    • 我不明白您关于“您的算法假定右侧的子树不能包含将出现在左侧顶视图中的节点”的观点。我的算法给出了你给出的例子的正确答案。
    • 你是对的;我误读了你的代码。我已经完全更新了我的答案,并提供了一个你的代码出错的案例。请看一看。
    • 我理解你的意思,是的,我的逻辑确实假设首先访问最高节点,但我仍然无法理解不是这种情况。同样对于上面的例子,你给出了,我的算法给出了正确的答案。两种情况我都测试过,(1)6是2的右节点,(2)6是10的右节点。
    • 刚刚在 geeksforgeeks.com 上测试了您修改后的代码,您的代码在与我的代码失败的相同测试用例中失败。我认为我们都在这里遗漏了一些东西。
    • 您能否编辑您的问题并添加失败的案例(输入/输出)。该网站需要注册。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多