LeetCode-95. 不同的二叉搜索树 II

在这里插入图片描述
思路:

考虑 [] 的所有解
null

考虑 [ 1 ] 的所有解
1

考虑 [ 1 2 ] 的所有解
  2
 /
1

 1
  \
   2

考虑 [ 1 2 3 ] 的所有解
    3
   /
  2
 /
1

   2
  / \
 1   3

     3
    /
   1
    \
     2

   1
     \
      3
     /
    2

  1
    \
     2
      \
       3

仔细分析,可以发现一个规律。首先我们每次新增加的数字大于之前的所有数字,所以新增加的数字出现的位置只可能是根节点或者是根节点的右孩子,右孩子的右孩子,右孩子的右孩子的右孩子等等,总之一定是右边。其次,新数字所在位置原来的子树,改为当前插入数字的左孩子即可,因为插入数字是最大的。

对于下边的解 
  2
 /
1

然后增加 3
1.3 放到根节点
    3
   /
  2
 /
1

2.3 放到根节点的右孩子
   2
  / \
 1   3
 
对于下边的解
 1
  \
   2

然后增加 3
1.3 放到根节点
     3
    /
   1
    \
     2
       
2.3 放到根节点的右孩子,原来的子树作为 3 的左孩子       
      1
        \
         3
        /
      2
      
3.3 放到根节点的右孩子的右孩子
  1
    \
     2
      \
       3

以上就是根据 [ 1 2 ] 推出 [ 1 2 3 ] 的所有过程,可以写代码了。由于求当前的所有解只需要上一次的解,所有我们只需要两个 list,pre 保存上一次的所有解, cur 计算当前的所有解。

# 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 treeCopy(self, root):
        if not root:
            return root
        newRoot = TreeNode(root.val)
        newRoot.left = self.treeCopy(root.left)
        newRoot.right = self.treeCopy(root.right)
        return newRoot

    def generateTrees(self, n: int) -> List[TreeNode]:
        if n == 0: return []
        pre = [None]
        # 每次增加一个数字
        for i in range(1, n+1):
            cur = []
            # 遍历之前的所有解
            for root in pre:
                # 插入到根节点
                insert = TreeNode(i)
                insert.left = root
                cur.append(insert)
                # 插入到右孩子,右孩子的右孩子...最多找 n 次孩子
                for j in range(n+1):
                    # 复制当前的树
                    root_copy = self.treeCopy(root)
                    # 找到要插入右孩子的位置
                    right = root_copy
                    k = 0
                    # 遍历 j 次找右孩子
                    while k < j:
                        if not right: break
                        right = right.right
                        k += 1
                        
                    # 到达 None 提前结束
                    if not right:
                        break
                    # 保存当前右孩子的位置的子树作为插入节点的左孩子
                    rightTree = right.right
                    insert = TreeNode(i)
                    # 右孩子是插入的节点
                    right.right = insert
                    # 插入节点的左孩子更新为插入位置之前的子树
                    insert.left = rightTree
                    # 加入结果中
                    cur.append(root_copy)
            pre = cur
        return pre

作者:windliang
链接:https://leetcode.cn/problems/unique-binary-search-trees-ii/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-2-7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码:

posted @ 2022-06-06 17:00  小Aer  阅读(2)  评论(0编辑  收藏  举报  来源