第六章 二叉树 part06
今日内容:654.最大二叉树、 617.合并二叉树、 700.二叉搜索树中的搜索、 98.验证二叉搜索树
代码随想录:代码随想录
今天的题第一遍都是能写出来的,但是看了参考答案后还是有比较大的启发
654.最大二叉树
题意:给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
- 二叉树的根是数组中的最大元素。
- 左子树是通过数组中最大值左边部分构造出的最大二叉树。
- 右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
思路:和参考代码思路大体一致,就是先找到最大的,然后划分左右数组继续递归,其中要注意边界情况。
而答案中:先判断是否>0,就直接构造左子树;构造右子树也是同理。(代码量会少,细品)
class Solution:
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
if len(nums) == 1:
return TreeNode(nums[0])
node = TreeNode(0)
# 找到数组中最大的值和对应的下标
maxValue = 0
maxValueIndex = 0
for i in range(len(nums)):
if nums[i] > maxValue:
maxValue = nums[i]
maxValueIndex = i
node.val = maxValue
# 最大值所在的下标左区间 构造左子树
if maxValueIndex > 0:
new_list = nums[:maxValueIndex]
node.left = self.constructMaximumBinaryTree(new_list)
# 最大值所在的下标右区间 构造右子树
if maxValueIndex < len(nums) - 1:
new_list = nums[maxValueIndex+1:]
node.right = self.constructMaximumBinaryTree(new_list)
return node
617.合并二叉树
题意:
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
思路:
这个参考答案的方法有几个很妙的地方。1、“有一个节点为空就返回另一个,另一个为空就返回None”,这样可以比直接创建一个val=“0”节点节省空间,细品,真的很细。2、直接在一个二叉树上加减而不是创建一个新的,也节省了空间,太细了。
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
# 递归终止条件:
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
if not root1:
return root2
if not root2:
return root1
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
root1.val += root2.val # 中
root1.left = self.mergeTrees(root1.left, root2.left) #左
root1.right = self.mergeTrees(root1.right, root2.right) # 右
return root1
700.二叉搜索树中的搜索
题意:给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。
思路:巧妙利用了二叉搜索树的结构。还有一个思想就是递归中,找不到但是也不太需要输出的情况下可以不return,就相当于单纯找一遍,只输出找得到的情况。
class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
# 为什么要有返回值:
# 因为搜索到目标节点就要立即return,
# 这样才是找到节点就返回(搜索某一条边),如果不加return,就是遍历整棵树了。
if not root or root.val == val:
return root
if root.val > val:
return self.searchBST(root.left, val)
if root.val < val:
return self.searchBST(root.right, val)
98.验证二叉搜索树
题意:
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
思路:首先要知道二叉搜索树是啥,这是一个有点坑的地方,因为不光是要比较左右节点的val,而是比较整个左右子树中节点的val。
我的思路就是:把子树遍历一遍输出一个数组,然后找出数组中的max或者min与root.val比较
参考代码有点妙:把整个二叉树转化为中序遍历的数组,然后根据它的结构就会惊喜的发现,woc!!!这TM是一个递增的数组!
class Solution:
def __init__(self):
self.vec = []
def traversal(self, root):
if root is None:
return
self.traversal(root.left)
self.vec.append(root.val) # 将二叉搜索树转换为有序数组
self.traversal(root.right)
def isValidBST(self, root):
self.vec = [] # 清空数组
self.traversal(root)
for i in range(1, len(self.vec)):
# 注意要小于等于,搜索树里不能有相同元素
if self.vec[i] <= self.vec[i - 1]:
return False
return True