一、题目
牛客题目链接:BM35 判断是不是完全二叉树
难度系统:中等
题目描述:
给定一个二叉树,确定他是否是一个完全二叉树。
完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)
数据范围:节点数满足 1≤n≤100
样例图1:

样例图2:

样例图3:

示例1:
输入:{1,2,3,4,5,6}
返回值:true
示例2:
输入:{1,2,3,4,5,6,7}
返回值:true
示例3:
输入:{1,2,3,4,5,#,6}
返回值:false
二、解题思路&代码实现
方案一:广度优先遍历(层次遍历)
解题思路:
通过完全二叉树的定义我们可以知道完全二叉树的叶子节点只能出现在最下层和次下层。
可以借助队列来辅助实现层次遍历。
从上到下遍历所有层,每层从左到右,只有次下层和最下层才有叶子节点,其他层出现叶子节点就意味着不是完全二叉树。
具体实现:
- step 1:先判断空树一定是完全二叉树。
- step 2:初始化一个队列辅助层次遍历,将根节点加入。
- step 3:逐渐从队列中弹出元素访问节点,如果遇到某个节点为空,进行标记,代表到了完全二叉树的最下层,若是后续还有访问,则说明提前出现了叶子节点,不符合完全二叉树的性质。
- step 4:否则,继续加入左右子节点进入队列排队,等待访问。
复杂度分析:
- 时间复杂度:O(n) ,其中nn为二叉树节点数,层次遍历最坏情况下遍历每一个节点。
- 空间复杂度:O(n) ,最坏情况下,层次队列的最大空间为O(n) 。
代码实现:
golang:
package main
import "container/list"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func isCompleteTree(root *TreeNode) bool {
if root == nil {
return true
}
queue := list.New()
queue.PushBack(root)
// 标记是否遇到了不完整的节点
encounteredNull := false
for queue.Len() > 0 {
node := queue.Remove(queue.Front()).(*TreeNode)
// 如果遇到了null节点,标记为true
if node == nil {
encounteredNull = true
continue
}
// 如果之前已经遇到了null节点,但当前节点不为空,说明不是完全二叉树
if encounteredNull {
return false
}
// 将左右子节点加入队列,如果为空也加入(用nil表示)
queue.PushBack(node.Left)
queue.PushBack(node

最低0.47元/天 解锁文章
2282

被折叠的 条评论
为什么被折叠?



