一、226.翻转二叉树
这道题目 一些做过的同学 理解的也不够深入,建议大家先看我的视频讲解,无论做过没做过,都会有很大收获。题目链接/文章讲解/视频讲解:代码随想录
1. 整体思路
(1)递归三部曲:1)确定递归函数的参数和返回值;2)确定终止条件;3)确定单层递归逻辑。
(2)思考清楚采用哪种遍历方式,中序/前序/后序。在本题目中只能使用前序或者后序遍历,不能使用中序遍历,因为中序遍历是左中右的遍历顺序,在遍历左子树后遍历中间结点,并且将左子树和右子树进行交换,那么最后去遍历右子树时,仍然是交换后的左子树,此时应该遍历的右子树已经被交换至左边了,无法进行遍历原来的右子树,不满足题意,所以不可以使用中序遍历。
2. 细节思路
(1)首先判断给定的结点是否为空,如果为空,则直接返回空。
(2)前序遍历:首先将中间结点的左右子树进行交换,然后再递归遍历左子树,最后递归遍历右子树;后序遍历则是先遍历左右子树,最后进行交换。
(3)最后返回根结点即可。
3. 完整代码
# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if root is None:
return None
root.left, root.right = root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root
二、101. 对称二叉树
先看视频讲解,会更容易一些。题目链接/文章讲解/视频讲解:代码随想录
1. 整体思路
(1)确定递归函数的参数和返回值:递归函数的参数是给一个根结点root,要求返回一个布尔值,即判断二叉树是否对称。
(2)确定终止条件:遍历树的全部结点并进行比较。
(3)确定单层递归逻辑:比较二叉树左子树的外侧结点和右子树的外侧结点、右子树的内侧结点和左子树的内侧结点,最后进行中间结点遍历,也就是将前两个的内外侧结点的比较结果返回给父节点,如果前两个比较结果均为true,那么中间结点也为true。
注意:什么情况下使用后序遍历?
收集孩子信息,并且向上一层返回-->这种情况下必须使用后序遍历
2. 细节思路
(1)首先对传入的树结点的左右子树进行比较判断:
1)若左右子树均为空,那么直接返回true,因为单一的根结点也是对称的;2)若左子树为空,右子树不为空:那么直接返回false,必然不可能是对称二叉树;3)若左子树不为空但右子树为空:直接返回false,必然不可能是对称二叉树;4)若左右子树均不为空,但值不相等:直接返回false;5)若左右子树均不为空且值相等:进入下一层循环继续判断。
(2)后序遍历:
1)左:比较左子树的外侧结点(left.left)和右子树的外侧结点(right.right)是否一致,若相等则返回true。
2)右:比较左子树的内侧结点(left.right)和右子树的内侧结点(right.left)是否一致,若相等则返回true。
3)中:将上述两个比较结果返回给中间结点父节点,若同时为true,中间结点才为true。
(3)最后返回结果判断是否为对称二叉树。
3. 完整代码
class TrueNode:
def __init__(self, val = 0, left = None, right = None):
self.val = val
self.left = left
self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if root is None:
return True
return self.compare(root.left, root.right)
def compare(self, left, right):
if left == None and right != None: return False
elif left != None and right == None: return False
elif left == None and right == None: return True
elif left.val != right.val: return False
elif left.val == right.val:
outside = self.compare(left.left, right.right)
inside = self.compare(left.right, right.left)
res = outside and inside
return res
注意,以下是debug错误:
三、104.二叉树的最大深度
什么是深度,什么是高度,如何求深度,如何求高度,这里有关系到二叉树的遍历方式。大家 要先看视频讲解,就知道以上我说的内容了,很多录友刷过这道题,但理解的还不够。
题目链接/文章讲解/视频讲解: 代码随想录
1. 整体思路
(1)知识点总结:
深度:树中任意节点到根结点的距离,一般自上而下遍历,所以采用前序遍历。
高度:树中任意节点到叶子结点的距离,一般自下而上遍历,即左右结点的高度向上传递给父节点,所以采用后序遍历。
注意:最大深度 <=> 根结点的高度,本题求深度按理应该使用前序遍历,但由于要求最大深度,也就是求根结点的高度,所以可以采用后序遍历。
(2)整体思路:后序遍历,求根结点左右子树二者中的较大高度,最后加1,就是根结点的最大高度。
2. 细节思路
(1)返回值为int:判断传入的根结点是否为空,为空则输出0;
(2)接下来调用递归函数遍历计算左右子树的高度;
(3)使用max函数计算最大的子树高度,再加1,得到最后根结点的最大高度。
3. 完整代码
# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
l_depth = self.maxDepth(root.left)
r_depth = self.maxDepth(root.right)
depth = max(l_depth, r_depth)+1
return depth
4. 扩展:599.N叉树的最大深度
完整代码:
"""
# Definition for a Node.
class Node:
def __init__(self, val: Optional[int] = None, children: Optional[List['Node']] = None):
self.val = val
self.children = children
"""
class Solution:
def maxDepth(self, root: 'Node') -> int:
if root is None:
return 0
max_depth = 1
for child in root.children:
max_depth = max(max_depth, self.maxDepth(child)+1)
return max_depth
四、111.二叉树的最小深度
先看视频讲解,和最大深度 看似差不多,其实 差距还挺大,有坑。题目链接/文章讲解/视频讲解:代码随想录
1. 整体思路
注意:题目中给定的最小深度是从根节点到最近叶子节点的最短路径上的节点数量。即左子树为空,则最小深度不为根结点0,因为根结点它不是叶子结点。
整体思路与104.求二叉树最大深度基本相同,但需要注意一个坑,当根左子树为空,右子树不为空时,最小深度并不是直接0+1,因为本题的最小深度是根节点到最近叶子结点的距离,所以最小深度应该是右子树的高度+1。
2. 完整代码
# 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 minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
#后序遍历:
#左
l_depth = self.minDepth(root.left)
#右
r_depth = self.minDepth(root.right)
#中
if root.left is None and root.right is not None:
return r_depth+1
if root.right is None and root.left is not None:
return l_depth+1
return min(l_depth, r_depth)+1