写在前边的话
今天是代码随想录的第三天,今天训练的主要方法还是递归法,因此我就采取先想思路然后看视频讲解分析总结的步骤啦。前边总结了要先想想遍历顺序,要记得呀,那就开始啦!
110.平衡二叉树
题目链接
题目难度
简单
文章讲解
视频讲解
代码随想录视频讲解
递归法解题思路
1. 遍历顺序:后序
2. 递归三步曲:
1)入参:二叉树当前节点;返回值:当前节点的最大深度。
2)终止条件:节点为空,返回0。
3)单次递归逻辑:分别获取左右孩子的最大深度,如果深度为-1表示已经不是平衡二叉树了则返回-1;计算左右孩子的最大深度差值,差值大于1则不是平衡二叉树返回-1,否则父亲节点的深度为1+max(左孩子的最大深度,右孩子的最大深度)。
代码编写
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 isBalanced(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
if self.getHeigth(root) == -1:
return False
else:
return True
def getHeigth(self, node):
if not node:
return 0
left_heigth = self.getHeigth(node.left)
if left_heigth == -1:
return -1
right_heigth = self.getHeigth(node.right)
if right_heigth == -1:
return -1
if abs(left_heigth - right_heigth) > 1:
return -1
else:
return 1+max(left_heigth, right_heigth)
java
257. 二叉树的所有路径
题目链接
题目难度
简单
文章讲解
视频讲解
递归法解题思路
递归+回溯
1. 遍历顺序:前序遍历,这样才能形成题目描述的那样使得父亲节点指向孩子节点,从而生成对应的路径。
2. 递归三步曲:
1)入参:当前节点,保存当前路径的数组path,保存全部路径的数组res。返回:保存全部路径的数组res。
2)终止条件:注意不是node为None的时候了,而是如果当前节点的左右孩子都为None就终止了。
3)单次递归逻辑:中:保存当前节点的值到path,这个时候就需要检查下当前节点的左右孩子是不是为空,如果为空则当前路径结束,把path里数据生成路径并保存到res中,当次递归也就终止了;否则的话遍历左孩子:如果左孩子不为空则对左孩子进行递归逻辑直到这条路径结束,此时就要回溯节点了,要回溯到父亲节点;回溯到父亲节点以后就要遍历右孩子了:如果右孩子不为空,则对右孩子进行递归逻辑直到这条路径结束,然后依然也要回溯到父亲节点。
注意:回溯和递归是一一对应的,有一个递归,就要有一个回溯。
代码编写
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 trversal(self, node, path, res):
path.append(str(node.val)) # 中
if not node.left and not node.right:
res.append("->".join(path))
return
if node.left: # 左
self.trversal(node.left, path, res)
path.pop() # 回溯
if node.right: # 右
self.trversal(node.right, path, res)
path.pop() # 回溯
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
res = []
path = []
if not root:
return res
self.trversal(root, path, res)
return res
java
404.左叶子之和
题目链接
题目难度
简单
文章讲解
视频讲解
递归法解题思路
1. 遍历顺序:后序遍历
2. 递归三步曲:
1)入参:二叉树根节点;返回值:左叶子节点之和
2)终止条件:当前节点为空返回0;当前节点的左右孩子都为空返回0。
3)单次递归逻辑:遇到叶子节点记录叶子节点的数值。通过递归求左子树左叶子节点之和和右子树左叶子节点之和,最后再相加。
代码编写
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 sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
if not root.left and not root.right:
return 0
left_sum = self.sumOfLeftLeaves(root.left) # 左
if root.left and not root.left.left and not root.left.right:
left_sum = root.left.val
right_sum = self.sumOfLeftLeaves(root.right) # 右
res = left_sum + right_sum # 中
return res
java
222.完全二叉树的节点个数
题目链接
题目难度
简单
文章讲解
代码随想录222.完全二叉树的节点个数文章讲解
视频讲解
代码随想录222.完全二叉树的节点个数视频讲解
递归法解题思路
1. 遍历顺序:后序遍历
2. 递归三步曲:(普通二叉树)
1)入参:根节点;返回值:节点数量
2)终止条件:节点空,返回0,即节点数是0
3)单次递归逻辑:分别获取左右子树的节点数,最后求和加1就是二叉树的总节点数。
递归三部曲:(完全二叉树)
1)入参:根节点;返回值:节点数量
2)终止条件:节点空,返回0;分别一直往左和一直往右遍历节点并记录左子树深度和右子树深度,如果深度相同说明子树是满二叉树则用公式2^k-1计算节点数量。
3)单次递归逻辑:分别获取左右子树的节点数,最后求和加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 getNodesNum(self, node):
if not node:
return 0
left_num = self.countNodes(node.left) # 左
right_num = self.countNodes(node.right) # 右
res = left_num + right_num + 1 # 中
return res
def countNodes(self, root: Optional[TreeNode]) -> int:
return self.getNodesNum(root)
# *************************************************************
# 完全二叉树
# 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 countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left_depth = 0
right_depth = 0
left = root.left
right = root.right
while left:
left_depth += 1
left = left.left
while right:
right_depth += 1
right = right.right
if left_depth == right_depth:
print(f"left_depth: {left_depth}")
# return 2**(left_depth+1)-1
return (2<<left_depth) - 1
left_num = self.countNodes(root.left) # 左
right_num = self.countNodes(root.right) # 右
res = left_num + right_num + 1 # 中
return res
java
今日总结
今日的题目都是用递归方法解决的,加深了对于递归的理解,并且在练习过程中有意识的先去想遍历顺序,然后按照递归三步曲解题,但是发现自己对于单次递归的逻辑还是不太能够很好的梳理出来,感觉还是有的绕,后边继续加强连续吧。