0
点赞
收藏
分享

微信扫一扫

【LeetCode】96.不同的二叉搜索树

0.总结

  • 本问题尚未AC,原因是数字过大时,超出了时间限制。需要结合一个记忆化搜索过程。

1.题目

2.思想

思想:
是一个递归问题,考虑将不同的节点做根节点。然后将剩余的节点划分大小再作为左右子树。其可能性便是 ​​​num(left) * num(right)/2​​​ 左右子树的建树过程也如上述。
具体地说:

  • 依次遍历所有节点,让其作为根节点,同时得到左右子树节点集合
  • 遍历左右子树节点集合,依次选择其中一个作为根节点,重复上述步骤

3.代码

class Solution:
def numTrees(self, n: int) -> int:
res = 0
# 搞一个记忆化搜索,如果之前搜索过这个答案,直接返回输出
tuple2num={} # 存储每个tuple可能得到的建树数目
for i in range(n+1): # i 为root
left = [j for j in range(1,i)]
right = [j for j in range(i+1,n+1)]
# 得到左右节点集合
res += self.build_bin_search_tree(i,left,right,tuple2num)
return res/2

# 建二叉搜索树
def build_bin_search_tree(self,root,left,right,tuple2num):
# 边界返回条件
if len(left) == 0 and len(right) == 0: # 只有(放根节点)这一种选择
return 1

# 建左子树
left_num = 0 # 左子树的个数
len_left = len(left)
for left_root in range(len(left)):
left_left = [left[j] for j in range(0,left_root)] # 左子树的左子树
left_right = [left[j] for j in range(left_root+1,len_left)]
# if tuple(left_left) in tuple2num: # 如果这个已经搜索过,直接返回

left_num += self.build_bin_search_tree(left_root,left_left,left_right)


# 建右子树
right_num = 0
len_right = len(right)
for right_root in range(len_right):
right_left = [right[j] for j in range(0,right_root)]
right_right = [right[j] for j in range(right_root+1,len_right)]
right_num += self.build_bin_search_tree(right_root,right_left,right_right)

# 因为这里存在两种选择,所以最后要除以2
return max(left_num,1) * max(right_num,1)

s = Solution()
res = s.numTrees(1)
print(res/2)

举报

相关推荐

0 条评论