给定值列表,生成所有有效的二进制搜索树

时间:2019-04-03 19:20:09

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

您好,我正在尝试解决有关leetcode [https://leetcode.com/problems/unique-binary-search-trees-ii/]的以下问题。

我知道我可以使用该解决方案,但我尝试以自己的方式解决该问题,但我被困住了,我想知道它是否可以按照我的方式解决。 这是代码:

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

def generateTrees(myrange, n, res = None):
    if res == None:
        res = []
    if myrange == []:
        res.append(None)
        return
    for root in myrange:
        res.append(root)
        generateTrees([i for i in range(root) if i in set(myrange)], n, res) #leftchild
        generateTrees([i for i in range(root+1, n) if i in set(myrange)], n, res) #rightchild
    return res

最初myrange只是包含节点值的列表,而nmyrange的长度。

我这样做的方式是一种DFS,在其中循环遍历节点,使每个节点成为根,然后对左右子树进行相同操作以获取所有组合。但是我面临的问题是我无法弄清楚如何管理res以便从我的递归回溯中删除元素(并使其res仅包含有效的bst,然后将其放入其他列表,这将是我的实际结果。

如果您认为我的方法是正确的还是不好的,我想提出一些建议,甚至只是评论。

1 个答案:

答案 0 :(得分:1)

问题:

  • 正如您所提到的,您的代码仅创建一个列表,并一直附加到该列表。
  • 即使您要解决此问题,列表也永远不会以BFS的顺序出现,这就是问题示例所暗示的含义。
  • 对于选定的根,您需要列出其可能的左子树及其可能的右子树的所有组合-如果需要,则为笛卡尔乘积。您的代码中缺少此逻辑。

我会

  • 不将res作为参数传递给递归函数。只需返回它,然后让呼叫者处理它即可。
  • 不使用范围,因为这似乎只会使事情复杂化。 if i in set(myrange)似乎是一种无效的方式来获得两个范围之间的重叠。相反,我会将范围的两个极端作为单独的参数传递。
  • 使用TreeNode类实际创建树,并在以后处理生成所需的输出格式。
  • 要生成输出格式,您需要在树中进行BFS遍历,这可以作为TreeNode上的方法来实现。

这是我认为可行的方法:

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

    def breadth_first(self):
        lst = []
        todo = [self]
        while any(todo):
            node = todo.pop(0)
            lst.append(node.val if node else None)
            if node:
                todo.append(node.left)
                todo.append(node.right)
        return lst

def generateTrees(n):
    def recur(start, end): # end is not included
        if start >= end:
            return [None]
        trees = []
        for root in range(start, end):
            lefts = recur(start, root)
            rights = recur(root+1, end)
            # Cartesian product:
            for left in lefts:
                for right in rights:
                    # Start with a new tree, and append to result
                    tree = TreeNode(root)
                    tree.left = left
                    tree.right = right
                    trees.append(tree)
        return trees
    return recur(1, n+1)

# Create the trees as a list of TreeNode instances:
trees = generateTrees(3)
# Convert to a list of lists 
print([tree.breadth_first() for tree in trees])