题目分析
- 题目给出一课树的根节点作为输入
- 题目要求我们判断该树是否为完全二叉树
方法一:层序遍历
- 实现思路
- 对于完全二叉树,我们关心该树每一层从左到右是否是完全连续的
- 因此层序遍历可以按照层的规则进行遍历
- 在某一层的遍历过程中,如果我们遇到了一个空指针位置,则继续遍历有两种情况
- 如果继续遍历,后面的节点全都是空指针节点,则说明该树是完全二叉树
- 如果继续遍历,后面的节点重新出现了非空节点,则说明该树非完全二叉树
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return bool布尔型
#
class Solution:
def isCompleteTree(self , root: TreeNode) -> bool:
# write code here
import queue
q = queue.Queue()
reachNull = False
q.put(root)
while not q.empty():
cur = q.get()
if not cur:
reachNull = True # 发现空节点
continue
else:
if reachNull: # 发现空节点之后存在非空节点
return False
q.put(cur.left) # 继续遍历左右节点
q.put(cur.right)
return True
复杂度分析
- 时间复杂度:O(n),对所有的节点都需要遍历一遍
- 空间复杂度:O(n),引入了队列的结构,队列的空间最大开销取决于树中节点最多的一层,对于完全二叉树,最多的一层节点数量有(n+1)/2个节点,可以达到O(n)的数量级
方法二:广度优先遍历编号
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @return bool布尔型
#
class Solution:
def isCompleteTree(self , root: TreeNode) -> bool:
# write code here
nodes = [(root, 1)]
i = 0
while i < len(nodes):
node, v = nodes[i]
i += 1 # 计数当前是第几个节点
if node:
nodes.append((node.left, 2*v)) # 继续为左子节点编号
nodes.append((node.right, 2*v+1)) # 继续为右子节点编号
return nodes[-1][1] == i
复杂度分析
- 时间复杂度:O(n),对所有的节点遍历一次的时间代价
- 空间复杂度:O(n),用一个列表记录了所有的节点信息和编号的空间代价