【问题标题】:Binary Tree Level Order Traversal in PythonPython中的二叉树级顺序遍历
【发布时间】:2019-10-13 17:24:26
【问题描述】:

给定以下树:

我应该返回从左到右遍历树的级别顺序: 所以上面的例子会输出一个列表列表:

[[3],[9,20],[15,7]]

我写了以下代码,想法是将节点值及其深度递归地存储在队列中,然后迭代队列元组并将中间列表 O 放入中间列表中,如果没有更多相同深度的节点将 O 附加到输出并清空 O 等等在。但是我的代码 Timeout 有什么帮助吗?

import queue

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        def helper(root,res,level):
            if not root:
                return res
            l=level+1
            res.put((root.val,level))
            helper(root.left,res,l)
            helper(root.right,res,l)

        res=queue.Queue()
        helper(root,res,0)

        d=1
        output=[]
        node,depth=res.get()
        output.append([node])
        while res:
            o=[]
            node,depth=res.get()
            while d ==depth:
                o.append(node)
                node,depth=res.get()
            else:
                d+=1
            output.append(o)    
            
        return output

【问题讨论】:

  • 请修正您的代码格式。
  • 如果 9 有 1 或 2 个孩子,你能给出预期的输出吗?只是想确定它是否是正确的前序树遍历,或者它是否是您正在寻找的 BFS 遍历。
  • @san 如果 9 有一个孩子说“6”,输出应该是 [ [3], [9,20], [6,15,7] ]
  • @ElenaGT,好吧,它是一个 BFS。我刚刚发布了下面的解决方案作为答案。如果有帮助,请随时接受并投票。 :-)

标签: python data-structures tree breadth-first-search


【解决方案1】:

这是我的广度优先搜索 (BFS) 迭代实现的代码,最终输出中每个级别的节点都在一个列表下:

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def BFS(self, root) -> int:
        level=1
        current=(root, level)
        s=set()
        result=[]
        Q = [current]
        while Q:
            current=Q.pop()
            level=current[1]
            if current[0] not in s:
                result.append([current[0].val, level])
                s.add(current[0])
            if current[0].left:
                Q.insert(0,(current[0].left, level+1))
            if current[0].right:
                Q.insert(0,(current[0].right, level+1))
        output=[]
        temp=[]
        level=1
        for val in result:
            if val[1]==level:
                temp.append(val[0])
            elif val[1] > level:
                output.append(temp)
                temp=[val[0]]
                level+=1
        output.append(temp)
        return output

测试:

n1=TreeNode(3)
n2=TreeNode(9)
n3=TreeNode(20)
n4=TreeNode(6)
n5=TreeNode(15)
n6=TreeNode(7)

n1.left=n2
n1.right=n3
n2.left=n4
n3.left=n5
n3.right=n6

sol1=Solution()
print(sol1.BFS(n1))
[[3], [9, 20], [6, 15, 7]]

【讨论】:

    【解决方案2】:

    感谢san 的回答。该解决方案帮助我解决了leetcode的问题107。我根据自己的理解稍微修改了一下。有两种方法可以解决这个问题,但我更喜欢使用 BFS 方式。此修订版本压缩队列中的 valuelevel。与其他教程提供的仅打印树中每个节点的 相比,它提供了更大的灵活性。

    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: 
            
            if root is None:
                return None
            
            level = 1
            q = []
            q.append((root,level)) # push both node and level.
            save = []
            
            while q:
                cur = q.pop(0)
                cur_node = cur[0]
                cur_level = cur[1]
                # print(cur_node.val)
                # print(cur_level)  
                save.append([cur_node.val, cur_level])
                if cur_node.left:
                    q.append((cur_node.left, cur_level+1))
                if cur_node.right:
                    q.append((cur_node.right, cur_level+1))
                    
            print(save) # once print, you will have the idea about how to reorgnized the required output.
            level = 1
            output = []
            temp = []
            for i in range(len(save)):
                cur = save[i]
                #print(cur)
                if cur[1] == level:
                    temp.append(cur[0])    
                if cur[1] != level:
                    output.insert(0, temp)
                    temp = []
                    temp.append(cur[0])
                    level = level + 1
                if i == len(save)-1:
                        output.insert(0, temp)
                
            return output
    

    【讨论】:

      【解决方案3】:

      您可以使用以下逻辑,打印出 BFS 中的节点。 如果您还需要,您也可以修改该方法以返回一个列表。

      def levelOrder(root):
      qroot = []
      print(root.info,end=' ')
      if root.left:
          qroot.append(root.left)
      if root.right:
          qroot.append(root.right)
      
      while(qroot):
          tmp = qroot[0]
          if tmp.left:
              qroot.append(tmp.left)
          if tmp.right:
              qroot.append(tmp.right)
      
          print (tmp.info,end=' ')
          qroot.pop(0)
      
      return
      

      您可以直接将值附加到新列表并返回相同的值,而不是打印值。

      【讨论】:

      • 您能否澄清一下这是否是为了解决 OP 最初的预期任务?我发现即使在修复了格式问题(缩进等)之后,这段代码也陷入了无限循环。我也不认为它会按照 OP 的要求以必要的顺序跟踪级别。很抱歉指出了这么多,但希望它有所帮助:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-01
      • 2020-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多