226.翻转二叉树
思考: 翻转二叉树其实就是需要遍历孩子结点,两两交换左右孩子节点。因而需要选择合适的二叉树遍历算法,前序和后序&层序 的方式均可以对该问题进行求解。
递归法
在写一次递归的内部函数时,只需要考虑在当前函数下的处理逻辑即可。
# 递归三部曲
# 确定递归的返回值和参数、确定终止条件、单次递归的函数体。
def invertTree(root):
# 前序遍历:中左右
if root == None :
return root
# swap(root.left,root.right)
invertTree(root.left)
invertTree(root.right)
# swap(root.left,root.right) # 后序遍历
# 递归法:在写函数体的时候仅考虑当前的处理逻辑即可。
def invert_func(node):
if not node:
return node
node.left,node.right = node.right,node.left
invert_func(node.left)
invert_func(node.right)
invert_func(root)
return root
迭代法
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 迭代法:前序遍历
if not root:
return root
stack = []
stack.append(root)
while stack:
node = stack[-1]
stack.pop()
# 如果二者有一个不为0则交换左右孩子节点
if node.left or node.right:
node.left,node.right = node.right,node.left
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return root
101.对称二叉树
利用后序遍历,收集孩子的信息向上一层返回
递归法
递归法中只有当两者的值都为真时才能够返回True
# 主要判断左子树和右子树是否是可以进行翻转的。
bool compare(left,right){
# 确定终止条件
if left and not right: return False
elif not left and right: return False
elif not left and not right:return True
elif left.val != right.val:return False
# 确定遍历主体函数,比较外侧和内侧节点
outside = compare(left.left,right.right)
inside = compare(left.right,right.left)
result = outside & inside
return result # 只有内外侧同时相同,才能够返回真值
}
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
# 递归法
if not root:
return True
def compare(node1,node2):
# 终止条件
if not node1 and not node2: # 都不存在
return True
elif not node1 and node2: # 有一个不存在
return False
elif node1 and not node2: # 有一个不存在
return False
elif node1.val != node2.val: #
return False
# 递归主体部分
outside = compare(node1.left,node2.right)
inside = compare(node1.right,node2.left)
if outside and inside : return True
return False
return compare(root.left,root.right)
迭代法
思想: 入栈和出栈,利用前序遍历的方式,将需要比较的两个结点压入栈中。
if not root.left and not root.right:
return True
elif not root.left or not root.right:
return False
else:
queue = deque([root.left, root.right])
while queue:
# 先判断是否都存在,然后将对应的元素一一弹出,先判断节点是否存在,然后判断值是否相等,如果值相等那么依次向队列中添入新的元素。
node1 = queue.pop()
node2 = queue.pop()
if not node1 and not node2:
continue
if not node1 or not node2:
return False
# 如果节点相同那么将两个值同时压入队列中
if node1.val == node2.val:
queue.append(node1.left)
queue.append(node2.right)
queue.append(node1.right)
queue.append(node2.left)
else:
return False
return True
100.相同的树
利用前序遍历,分别比较两棵树的孩子结点。
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
# 递归法
def compare(node1,node2):
# 终止条件
if not node1 and not node2: # 都不存在
return True
elif not node1 and node2: # 有一个不存在
return False
elif node1 and not node2: # 有一个不存在
return False
elif node1.val != node2.val: #
return False
# 递归主体部分
left = compare(node1.left,node2.left)
right = compare(node1.right,node2.right)
if left and right : return True
return False
return compare(p,q)
572.另一个树的子树
先找到树的结点,之后再利用比较二叉树是否相同的递归算法,返回对应结点的值所在的树是否相同即可。
# 递归法
def compare(node1,node2):
# 终止条件
if not node1 and not node2: # 都不存在
return True
elif not node1 and node2: # 有一个不存在
return False
elif node1 and not node2: # 有一个不存在
return False
elif node1.val != node2.val: #
return False
# 递归主体部分
left = compare(node1.left,node2.left)
right = compare(node1.right,node2.right)
if left and right : return True
return False
# 先找到root中和subRoot相等的父结点
p = None
q = subRoot
stack = [root]
result = []
while stack:
node = stack[-1]
stack.pop()
if node.val == subRoot.val:
p = node
result.append(compare(p,q))
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
if True in result: return True
return False
二叉树阶段性总结
- 针对二叉树的问题,解题之前一定要想清楚究竟是前中后序遍历,还是层序遍历。
- 二叉树题目,确定遍历方式很重要。