思路:递归:子问题和原问题相似,适用于递归实现
递:从原问题出发,把问题分解成更小的子问题
尽头就是边界条件,返回的过程就是归
整棵树的最大深度=max(左子树的最大深度,右子树的最大深度)+1
代码实现:
方法二:设置一个全局变量x,在递归过程中不仅把节点传下去,也把这个路径所包含的节点个数也传下去,然后更新x的值,最终全局变量的值就是最大深度
代码:
这里的cnt可以理解为这个节点前有多少个节点,第一轮cin=1,因为有根节点3,然后将1作为cnt带入到左右子树根节点中,也就是这时候的左右子树根节点前已经存在一个节点。
强化训练1:100. 相同的树
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入:p = [1,2,3], q = [1,2,3] 输出:true
思想:判断是否相同的思路是:判断这两个节点的值是否相同+这两个节点的左右树是否相同
另外边界条件是,当有一个节点为空时,如果这两个节点相同,返回true否则fasle
# 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 isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p is None or q is None:
return p is q
return p.val==q.val and self. isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
变形:101. 对称二叉树
给你一个二叉树的根节点 root
, 检查它是否轴对称。
输入:root = [1,2,2,3,4,4,3] 输出:true
思路:上题对比的是两个节点的左子树和右子树,这里改一下,A的左子树和B的右子树,A的右子树和B的左子树即可
代码:
# 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 isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p is None or q is None:
return p is q
return p.val==q.val and self. isSameTree(p.left,q.right) and self.isSameTree(p.right,q.left)
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
return self.isSameTree(root.left,root.right)
给定一个二叉树,判断它是否是
平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:true
核心思路:如果某个地方发生了 abs(left_h - right_h) > 1,就会返回 -1,这个 -1 会一路 return 到根节
总结
代码部分:
# 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 isBalanced(self, root: Optional[TreeNode]) -> bool:
def get_height(node: Optional[TreeNode]) -> int:
if node is None: return 0
left_h = get_height(node.left)
if left_h == -1: return -1 # 提前退出,不再递归
right_h = get_height(node.right)
if right_h == -1 or abs(left_h - right_h) > 1: return -1
return max(left_h, right_h) + 1
return get_height(root) != -1
方法二:比较容易理解的递归
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null){
return true;
}
int leftDepth = depth(root.left);
int rightDepth = depth(root.right);
return Math.abs(leftDepth-rightDepth)>1?false:isBalanced(root.left)&&isBalanced(root.right);
}
public int depth(TreeNode root){
if(root == null){
return 0;
}
return Math.max(depth(root.left),depth(root.right))+1;
}
}
这里两种方法都用到了求深度的递归,以及一直比较左树高度这个递归,也就是两层递归
给定一个二叉树的 根节点 root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1,2,3,null,5,null,4] 输出: [1,3,4]
思想:先递归右子树,再递归左子树,顺序不能反了,记录递归深度,如果递归深度等于答案长度,就要加进去
代码:
# 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 rightSideView(self, root: Optional[TreeNode]) -> List[int]:
ans=[]
def f(node,depth):
if node is None:
return
if depth==len(ans):
ans.append(node.val)
f(node.right,depth+1)
f(node.left,depth+1)
f(root,0)
return ans