96、不同的二叉搜索树
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
解:按照第95题的思路就可以,只不过要把集合换成计数,为了加快速度要储存中间结果
class Solution:
def numTrees(self, n: int) -> int:
if n==0:
return 0
def countTree(k,ans):
if k==1:
ans.append(1)
return 1
if k==2:
ans.append(2)
return 2
count=0
for i in range(1,k+1):
count=count+ans[i-1]*ans[k-i]
ans.append(count)
return ans[k]
ans=[1]
for i in range(1,n+1):
a=countTree(i,ans)
return a
执行用时:40 ms, 在所有 Python3 提交中击败了67.67%的用户
内存消耗:13.6 MB, 在所有 Python3 提交中击败了86.21%的用户
97、交错字符串
给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
解法一:最简单的办法就是递归,根据s1或者s2第一个元素与s3的关系进行分类讨论,只可惜最后超时了
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
if sorted(s1+s2)!=sorted(s3):
return False
if not s1 and s2==s3:
return True
elif not s1 and s2!=s3:
return False
elif not s2 and s1==s3:
return True
elif not s2 and s1!=s3:
return False
elif s1[0]!=s3[0] and s2[0]!=s3[0]:
return False
elif s1[0]==s3[0] and s2[0]==s3[0]:
if (self.isInterleave(s1[1:],s2,s3[1:])) or (self.isInterleave(s1,s2[1:],s3[1:])):
return True
else:
return False
elif s1[0]==s3[0]:
if (self.isInterleave(s1[1:],s2,s3[1:])):
return True
else:
return False
else:
if (self.isInterleave(s1,s2[1:],s3[1:])):
return True
else:
return False
解法二:使用回溯不成功,但是我们又没有其它的办法(dfs的效果可能更差),所以我们可以考虑二维的动态规划dp[i][j]代表s1[:i],s2[:j]与s3[:i+j]
如果s1[i-1]与s[j-1]均与s3[i+j-1]不相等那dp[i][j]=False
如果s1满足,那就看dp[i-1][j],s2满足就看dp[i][j-1]
初始条件是dp[0][j]与dp[i][0]
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
m=len(s1)
n=len(s2)
l=len(s3)
if m+n!=l:
return False
dp=[[False for _ in range(n+1)] for _ in range(m+1)]
dp[0][0]=True
for i in range(1,m+1):
if s1[i-1]==s3[i-1]:
dp[i][0]=dp[i-1][0]
else:
break
for j in range(1,n+1):
if s2[j-1]==s3[j-1]:
dp[0][j]=dp[0][j-1]
else:
break
for i in range(1,m+1):
for j in range(1,n+1):
dp[i][j]=(dp[i][j-1] and s2[j-1]==s3[i+j-1]) or (dp[i-1][j] and s1[i-1]==s3[i+j-1])
return dp[m][n]
执行用时:40 ms, 在所有 Python3 提交中击败了95.01%的用户
内存消耗:13.7 MB, 在所有 Python3 提交中击败了78.06%的用户
98、验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
解:用递归就可以,关键是怎么判定一个子树节点的上下界。每访问一次左子树,上界变为当前根节点,每访问一次右子树,下界变为当前根节点。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
def isValid(root,down,up):
if not root:
return True
if not down<root.val<up:
return False
return isValid(root.left,down,root.val) and isValid(root.right,root.val,up)
return isValid(root,float("-inf"), float("inf"))
执行用时:56 ms, 在所有 Python3 提交中击败了74.08%的用户
内存消耗:15.9 MB, 在所有 Python3 提交中击败了72.88%的用户
99、恢复二叉搜索树
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
解:先遍历一遍,得到所有元素并排序。
有了左子节点的个数和右子节点的个数就可以知道根节点该放谁了,然后把原集合按根节点分为两个集合,一个要填入左子树,一个要填入右子树
# 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 recoverTree(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
def travelTree(root,treeList1):
if not root:
return
travelTree(root.left,treeList1)
treeList1.append(root.val)
travelTree(root.right,treeList1)
def countTree(root):
treeList=[]
travelTree(root,treeList)
return len(treeList)
def putroot(tree,treeList1):
if not tree:
return
a=countTree(tree.left)
tree.val=treeList1[a]
putroot(tree.left,treeList1[:a])
putroot(tree.right,treeList1[a+1:])
return
treeList=[]
travelTree(root,treeList)
treeList.sort()
putroot(root,treeList)
return
执行用时:96 ms, 在所有 Python3 提交中击败了47.94%的用户
内存消耗:14 MB, 在所有 Python3 提交中击败了77.74%的用户
100、相同的树
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
解:本质上就是遍历树
# 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 isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and q:
return False
if not q and p:
return False
if not q and not p:
return True
return (self.isSameTree(p.left,q.left) and (p.val==q.val) and self.isSameTree(p.right,q.right))
执行用时:36 ms, 在所有 Python3 提交中击败了90.39%的用户
内存消耗:13.7 MB, 在所有 Python3 提交中击败了63.21%的用户