题目链接:654. 最大二叉树 - 力扣(Leetcode)
这一题的思路和前一天的构建二叉树类似,只是将划分左右的规则由中序遍历结果改为区间的最大值,因为题目描述中明确nums中所有值不相同,因此可以用index找到每个区间最大值的下标:
# 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 constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
def dfs(left, right):
# 左闭右开区间
if right <= left:
return None
max_index = nums.index(max(nums[left: right])) # 当前区间中最大值的下标
root = TreeNode(val=nums[max_index]) # 根节点
root.left = dfs(left, max_index)
root.right = dfs(max_index + 1, right)
return root
root = dfs(0, len(nums))
return root
题目链接:617. 合并二叉树 - 力扣(Leetcode)
本质上,这道题就是从一个节点的递归拓展到两个节点,不想额外创建一个返回二叉树,可以将root2的树合并到root1,最后直接返回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]:
# 将树2合并到树1
def dfs(node1, node2):
if not node2:
return node1 # node2为空可直接返回(不改变node1),已经包含都为空的情况
if not node1:
# node2不为空
return node2
# 都不为空
node1.val += node2.val
node1.left = dfs(node1.left, node2.left)
node1.right = dfs(node1.right, node2.right)
return node1
merged_root = dfs(root1, root2)
return merged_root
题目链接:700. 二叉搜索树中的搜索 - 力扣(Leetcode)
二叉搜索树的独特性质使其递归条件更简单,根据值的大小,遍历都有特定的方向:
# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
def search(node, val):
if not node:
return None
if val < node.val:
return search(node.left, val)
elif val > node.val:
return search(node.right, val)
else:
return node
return search(root, val)
迭代法更简单(莫名和二分查找很像,有序的情况下查找更简便),都不需要用额外的栈暂存节点:
# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
# 迭代
while root:
if root.val == val:
return root
elif root.val < val:
root = root.right
else:
root = root.left
return None
题目链接:98. 验证二叉搜索树 - 力扣(Leetcode)
之前做的,利用二叉搜索树的性质,获得其中序遍历的序列,如果序列有序,则为合法的二叉搜索树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def inorder(self, root, nums):
if not root:
return
self.inorder(root.left, nums) # left
nums.append(root.val) # mid
self.inorder(root.right, nums) # right
return nums
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
vals = []
vals = self.inorder(root, vals)
for i in range(1, len(vals)):
if vals[i] <= vals[i-1]:
return False
return True
递归写法:
# 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 __init__(self):
self.pre = None
def isValidBST(self, root: Optional[TreeNode]) -> bool:
def dfs(cur):
if not cur:
return True
# 中序遍历
left = dfs(cur.left)
if self.pre is not None and self.pre.val >= cur.val:
return False
self.pre = cur
right = dfs(cur.right)
return left and right
return dfs(root)