目录
任务
654. 最大二叉树
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
思路
做了昨天的利用前中序(或者中后)数组构建二叉树,就会做这道题,思路基本一致。按照算法,分割数组区域并创建即可。
class Solution:
def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums)==0: return None
index = 0
maxValue = float('-inf')
for i in range(len(nums)):
if nums[i] > maxValue:
maxValue = nums[i]
index = i
root = TreeNode(nums[index])
leftNums = nums[:index]
rightNums = nums[index+1:]
root.left = self.constructMaximumBinaryTree(leftNums)
root.right = self.constructMaximumBinaryTree(rightNums)
return root
617. 合并二叉树
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
思路
单层递归逻辑: 分情况合并当前节点
- 两树都不存在节点
- 两树只有一个存在,则返回有的那个
- 都存在,则将节点和相加并构建成新节点,并且分别递归的合并其左右子树
这道题也是结合了遍历过程和传统递归的思路
class Solution:
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1 and not root2: return None
if root1 and not root2: return root1
if not root1 and root2: return root2
if root1 and root2:
newRoot = TreeNode(root1.val + root2.val)
newRoot.left = self.mergeTrees(root1.left,root2.left)
newRoot.right = self.mergeTrees(root1.right,root2.right)
return newRoot
700.二叉搜索树中的搜索
思路
这道题很简单,递归的思路就是遍历节点,找到就返回,否则根据条件向相应的子树去找。
迭代的思路是,val较小就往当前节点左子树找,val较大就往当前节点的右子树找,直到找到或者到达None.
# 递归法
class Solution:
def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root: return None
if root.val == val: return root
if val < root.val: return self.searchBST(root.left,val)
else: return self.searchBST(root.right,val)
# 迭代法
class Solution:
def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
while root:
if val < root.val: root = root.left
elif val > root.val: root = root.right
else: return root
return None
98. 验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左
子树
只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
思路(错误)
想当然的解法是直接用递归,判断当前节点的局部逻辑是否满足(它比它右节点小,比它左节点大),然后再判断左右子树是否满足,全部满足则返回True。可惜这种思路是错误的。。反例 [5,4,6,null,null,3,7], 某节点必须比他的左子树所有的值小,右子树所有的值大。这个7大于了根节点的大小,违反了BST的定义
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
if not root: return True
elif not root.left and not root.right: return True
elif root.left and not root.right:
if root.val > root.left.val: return True
else:return False
elif not root.left and root.right:
if root.val < root.right.val: return True
else:return False
else:
if root.val > root.left.val and root.val < root.right.val:
return self.isValidBST(root.left ) and self.isValidBST(root.right)
else:
return False
思路(正确)
判断中序序列是否有序
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
lst = []
self.inorder(root,lst)
print(lst)
for i in range(len(lst)-1):
if lst[i] >= lst[i+1]: return False
return True
def inorder(self,root,lst):
if not root: return None
self.inorder(root.left,lst)
lst.append(root.val)
self.inorder(root.right,lst)
心得体会
更娴熟的掌握了单纯递归逻辑(局部+递归),以及递归序遍历流程的思路。
标签:right,return,val,self,Day17,二叉树,root,节点,Part5 From: https://www.cnblogs.com/haohaoscnblogs/p/18338498