记录刷题的过程。牛客和力扣中都有相关题目,这里以牛客的题目描述为主。该系列默认采用python语言。
1、二叉树的深度
1、问题描述:
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
2、数据结构:
二叉树
3、题解:
方法1:深度优先搜索,要想得到深度,就得知道左、右子树的深度,然后让左、右子树中最大的深度+1就得到根节点的深度。用递归
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def TreeDepth(self, pRoot):
# write code here
#DFS后序遍历
if not pRoot:
return 0
return max(self.TreeDepth(pRoot.left),self.TreeDepth(pRoot.right)) + 1
方法2:
广度优先搜索。我们定义一个记号,当遍历完一层时,就加1,遍历到最后一层时,也就找到了最大深度。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def TreeDepth(self, pRoot):
# write code here
#BFS
if not pRoot:
return 0
import collections
queue,res = collections.deque([pRoot]),0
while queue:
size = len(queue)
for _ in range(size):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res += 1
return res
4、复杂度分析:
方法1和方法2都是
时间复杂度:O(N)
空间复杂度:O(N)
2、平衡二叉树
1、问题描述:
2、数据结构:
二叉树
3、题解:
此题DFS加上剪枝。如果左右两个子树的深度差大于1,直接返回-1;如果不大于1,就得到最大深度(也就是上一题的思路),在算每个子树的深度时,都要判断深度差是不是超过了1.最后把其封装成一个函数,调用函数,判断返回值是否不等于-1,如果不等于-1,说明满足平衡二叉树。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def recur(root):
if not root:
return 0
left = recur(root.left)
if left == -1:
return -1
right = recur(root.right)
if right == -1:
return -1
return max(left, right) + 1 if abs(left - right) < 2 else -1
return recur(root) != -1
4、复杂度分析:
时间复杂度:O(N)
空间复杂度:O(N)
3、二叉树的最小深度
1、问题描述:
2、数据结构:
二叉树
3、题解:
方法1:DFS
其实一开始是用第一个题的思路,直接把max改成min,但是没有通过。之后思考了一下,当左、右节点,有一个不存在时,返回的是根节点的深度,但其实应该返回的是存在的子树的深度。如下图:
如果用刚刚的思路,那么深度为根节点5的深度,也就是1,但其实最小深度应该为3.
所以在递归调用时,要加一个判断,如果遇到刚刚的情况,就返回存在的那个子树的深度+1就可以。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def minDepth(self, root: TreeNode) -> int:
# DFS
if not root:
return 0
left = self.minDepth(root.left)
right = self.minDepth(root.right)
if not root.left or not root.right: # 处理特殊情况,左、右节点有一个不存在
return left + 1 if right == 0 else right + 1 #返回存在的那个子树+1
return min(left, right) + 1
方法2:BFS
比二叉树的最大深度在BFS每层时多了一个判断:如果是叶子节点就返回depth。
class Solution:
def minDepth(self, root: TreeNode) -> int:
#BFS
if not root: return 0
queue = collections.deque()
queue.append(root)
depth = 0
while queue:
depth += 1
size = len(queue)
for i in range(size):
node = queue.popleft()
if not node.left and not node.right:
return depth
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return -1
4、复杂度分析:
时间复杂度:O(N)
空间复杂度:O(N)