今天的第二篇笔记,终于算是追上进度了,不过也跟今天题目较为简单有关,除了验证二叉树卡的久了点其余的感觉做起来都还顺手。654. 最大二叉树,617. 合并二叉树,700. 二叉搜索树中的搜索,98. 验证二叉搜索树。像是最大二叉树就是用昨天的构造方法进行切分,二叉搜索树的搜索就是利用遍历以及二分。合并稍微做久了点是第一次接触两个数遍历,有点不清楚怎么写,但研究了下还是做完了。
617. 合并二叉树
其实遍历两个树加和的思路,就是利用一个树遍历,将另一棵树相同的节点的值加过来就行,就像代码中用的都是root1。相当于是把root1看成一个数组,把root2这个数组对应index的数加过来。当然也可以自己新创建一个树,然后把两棵树相加放进来。这题感觉迭代法比递归法难一些,主要是条件判断写多了一点,就是两棵树都有的节点,做加和,左无右有则直接左等于右,左有右无就是直接是root1,其余的都还是不算难。
# 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 mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1:
return root2
if not root2:
return root1
root1.val += root2.val
root1.left = self.mergeTrees(root1.left,root2.left)
root1.right = self.mergeTrees(root1.right,root2.right)
return root1
# 迭代
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1:
return root2
if not root2:
return root1
q = deque([(root1, root2)])
while q:
node1, node2 = q.popleft()
node1.val += node2.val
if node1.left and node2.left:
q.append([node1.left,node2.left])
elif not node1.left:
node1.left = node2.left
if node1.right and node2.right:
q.append([node1.right,node2.right])
elif not node1.right:
node1.right = node2.right
return root1
98. 验证二叉搜索树
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
挺麻烦的一道题,一开始递归没有一点思路,就拿迭代先顺顺思路,然后做完发现怎么调试都不对,才发现是所有左子树和右子树自身必须也是二叉搜索树,这个条件没满足,就是单纯的比较左节点小于中间节点,右节点大于中间节点。之后学到了一种思路,有点像是所有队列那种的迭代方法,就是保存一组数据(root, min, max),每次弹出一个节点,然后赋值本节点,最小值,最大值。当往左节点开始走的时候,节点的最大值就发生变化,因为他的最大值的上限就是它的父节点。同理往右节点走的时候,节点的最小值也要变化。如果往左走过也往右走过,那么最大最小值都会有了限制。在每个节点处进行比较,不符合该节点的min< val < max就返回False,全遍历完了就是True。
然后是递归,懂了迭代思路之后再转化为递归就方便了(也可能是我练熟了hh),首先递归结束条件和迭代的结束条件都是一样的,不满足此节点的min < val < max。然后开始往两边分别进行递归,当两边都是True的时候,返回True,因为这个不像之前求路径的只需要走一边也行,是需要左右都符合条件,所以递归的时候用and。
# 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 isValidBST(self, root: Optional[TreeNode]) -> bool:
# 队列迭代
if not root:
return None
q = deque([(root,float("-inf"),float("inf"))])
while q:
node, min_val, max_val = q.popleft()
if not (min_val < node.val < max_val):
return False
if node.left:
q.append((node.left, min_val, node.val))
if node.right:
q.append((node.right, node.val, max_val))
return True
def isValidBST(self, root: Optional[TreeNode]) -> bool:
#递归
def validate(node, min_val, max_val):
if not node:
return True
if not (min_val < node.val < max_val):
return False
node_left = validate(node.left,min_val,node.val)
node_right = validate(node.right,node.val,max_val)
return node_left and node_right
return validate(root, float('-inf'), float('inf'))