代码随想录算法训练营第20天|二叉树part06|654. 最大二叉树、 617.合并二叉树、 700.二叉搜索树中的搜索、 98.验证二叉搜索树
654. 最大二叉树
自己做
思路:
递归三件套:
- 确定参数
当前递归层要构建的树的数组nums
def constructMaximumBinaryTree(self, nums):
- 确定终止条件
传入的数组为空,返回None
if len(nums) == 0:
return None
- 确定单层递归的处理逻辑
# 获得最大值和最大值所在索引
max_val = max(nums)
max_val_index = nums.index(max_val)
# 构建结点
root = TreeNode(max_val)
# 确定左子树和右子树
left_nums = nums[ : max_val_index]
right_nums = nums[max_val_index+1: len(nums)]
# 构建左子树和右子树
if len(left_nums) != 0:
#print('left:', left_nums)
root.left = self.constructMaximumBinaryTree(left_nums)
if len(right_nums) != 0:
#print("right: ", right_nums)
root.right = self.constructMaximumBinaryTree(right_nums)
# 构建完成,返回root结点
return root
代码:
python
# 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 constructMaximumBinaryTree(self, nums): # 1.
"""
:type nums: List[int]
:rtype: TreeNode
"""
# 1. 传入参数为:构建树需要的数组、root
if len(nums) == 0:
return None
max_val = max(nums)
root = TreeNode(max_val)
max_val_index = nums.index(max_val)
#print(max_val_index)
left_nums = nums[ : max_val_index]
right_nums = nums[max_val_index+1: len(nums)]
if len(left_nums) != 0:
#print('left:', left_nums)
root.left = self.constructMaximumBinaryTree(left_nums)
if len(right_nums) != 0:
#print("right: ", right_nums)
root.right = self.constructMaximumBinaryTree(right_nums)
#print('root: ', root.val)
return root
617. 合并二叉树
自己做
思路:
依题目要求,只要两颗树同时前序遍历即可
遍历时需要考虑为空情况,需要特殊处理,代码所示
代码:
python
# 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 mergeTrees(self, root1, root2): # 1.
"""
:type root1: TreeNode
:type root2: TreeNode
:rtype: TreeNode
"""
# 遍历,前序遍历就可以
# 2.
if not root1 and not root2:
return None
# 3.
if root1 and root2:
# 求和
# 赋值
root = TreeNode(root1.val + root2.val)
root.left = self.mergeTrees(root1.left, root2.left)
root.right = self.mergeTrees(root1.right, root2.right)
elif root1 and not root2:
# root1不为空,root2为空
root = TreeNode(root1.val)
root.left = self.mergeTrees(root1.left, None)
root.right = self.mergeTrees(root1.right, None)
elif not root1 and root2:
# root1为空,root2不为空
root = TreeNode(root2.val)
root.left = self.mergeTrees(None, root2.left)
root.right = self.mergeTrees(None, root2.right)
return root
代码随想录
思路:
在终止条件部分:
if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1
进行了剪枝操作
代码:
python
递归
# 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 mergeTrees(self, root1, root2): # 1.
"""
:type root1: TreeNode
:type root2: TreeNode
:rtype: TreeNode
"""
# 遍历,前序遍历就可以
# 2.
if not root1 and not root2:
return None
# 3.
if root1 and root2:
# 求和
# 赋值
root = TreeNode(root1.val + root2.val)
root.left = self.mergeTrees(root1.left, root2.left)
root.right = self.mergeTrees(root1.right, root2.right)
return root
elif root1 and not root2:
# root1不为空,root2为空
'''
root = TreeNode(root1.val)
root.left = self.mergeTrees(root1.left, None)
root.right = self.mergeTrees(root1.right, None)
'''
return root1
elif not root1 and root2:
# root1为空,root2不为空
'''
root = TreeNode(root2.val)
root.left = self.mergeTrees(None, root2.left)
root.right = self.mergeTrees(None, root2.right)
'''
return root2
#return root
迭代
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
if not root1:
return root2
if not root2:
return root1
queue = deque()
queue.append(root1)
queue.append(root2)
while queue:
node1 = queue.popleft()
node2 = queue.popleft()
# 更新queue
# 只有两个节点都有左节点时, 再往queue里面放.
if node1.left and node2.left:
queue.append(node1.left)
queue.append(node2.left)
# 只有两个节点都有右节点时, 再往queue里面放.
if node1.right and node2.right:
queue.append(node1.right)
queue.append(node2.right)
# 更新当前节点. 同时改变当前节点的左右孩子.
node1.val += node2.val
if not node1.left and node2.left:
node1.left = node2.left
if not node1.right and node2.right:
node1.right = node2.right
return root1
700. 二叉搜索树中的搜索
自己做
思路:
二叉搜索树是一个有序树:
-
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
-
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值
-
它的左、右子树也分别为二叉搜索树
注意
有返回值的递归函数,再return时需要用一个变量将其接住,否则返回值不就没了
代码:
python
# 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 searchBST(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if root == None:
return None
if root.val == val:
return root
if root.val < val:
return self.searchBST(root.right, val)
if root.val > val:
return self.searchBST(root.left, val)
迭代
二叉搜索时的迭代不需要栈或者是队列,因为因为节点的有序性就帮我们确定了搜索的方向
第一次看到了如此简单的迭代法,是不是感动的痛哭流涕,哭一会~!!!
class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
while root:
if val < root.val: root = root.left
elif val > root.val: root = root.right
else: return root
return None
98. 验证二叉搜索树
自己做
思路:
问题在于如何判断一个树是否是二叉搜索树 ->递归
注意
但是这样做,有一个问题,看图所示,图中的不是二叉排序树
代码:
pyton
# 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 isValidBST(self, root):# 1.
"""
:type root: TreeNode
:rtype: bool
"""
# 问题在于如何判断一个树是否是二叉搜索树
# 2.
if root and not root.left and not root.right:
return True
if root and root.left and not root.right:
if root.val > root.left.val:
return True and self.isValidBST(root.left)
else:
return False
if root and root.right and not root.left:
if root.val < root.right.val:
return True and self.isValidBST(root.right)
else:
return False
if root and root.left and root.right:
if root.val > root.left.val and root.val < root.right.val:
return True and self.isValidBST(root.left) and self.isValidBST(root.right)
else:
return False
代码随想录
思路:
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
陷阱1:
不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了
我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。
代码:
python
# 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.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