加载中...
958-二叉树的完全性检验(Check Completeness of a Binary Tree)
发表于:2021-12-03 | 分类: 中等
字数统计: 1.1k | 阅读时长: 4分钟 | 阅读量:

原文链接: https://leetcode-cn.com/problems/check-completeness-of-a-binary-tree

英文原文

Given the root of a binary tree, determine if it is a complete binary tree.

In a complete binary tree, every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.

 

Example 1:

Input: root = [1,2,3,4,5,6]
Output: true
Explanation: Every level before the last is full (ie. levels with node-values {1} and {2, 3}), and all nodes in the last level ({4, 5, 6}) are as far left as possible.

Example 2:

Input: root = [1,2,3,4,5,null,7]
Output: false
Explanation: The node with value 7 isn't as far left as possible.

 

Constraints:

  • The number of nodes in the tree is in the range [1, 100].
  • 1 <= Node.val <= 1000

中文题目

给定一个二叉树,确定它是否是一个完全二叉树

百度百科中对完全二叉树的定义如下:

若设二叉树的深度为 h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。(注:第 h 层可能包含 1~ 2h 个节点。)

 

示例 1:

输入:[1,2,3,4,5,6]
输出:true
解释:最后一层前的每一层都是满的(即,结点值为 {1} 和 {2,3} 的两层),且最后一层中的所有结点({4,5,6})都尽可能地向左。

示例 2:

输入:[1,2,3,4,5,null,7]
输出:false
解释:值为 7 的结点没有尽可能靠向左侧。

 

提示:

  1. 树中将会有 1 到 100 个结点。

通过代码

官方题解

方法 1:广度优先搜索

想法

这个问题可以简化成两个小问题:用 (depth, position) 元组表示每个节点的”位置“;确定如何定义所有节点都是在最左边的。

假如我们在深度为 3 的行有 4 个节点,位置为 0,1,2,3;那么就有 8 个深度为 4 的新节点位置在 0,1,2,3,4,5,6,7;所以我们可以找到规律:对于一个节点,它的左孩子为:(depth, position) -> (depth + 1, position * 2),右孩子为 (depth, position) -> (depth + 1, position * 2 + 1)。所以,对于深度为 d 的行恰好含有 $2^{d-1}$ 个节点,所有节点都是靠左边排列的当他们的位置编号是 0, 1, ... 且没有间隙。

一个更简单的表示深度和位置的方法是:用 1 表示根节点,对于任意一个节点 v,它的左孩子为 2*v 右孩子为 2*v + 1。这就是我们用的规则,在这个规则下,一颗二叉树是完全二叉树当且仅当节点编号依次为 1, 2, 3, ... 且没有间隙。

算法

对于根节点,我们定义其编号为 1。然后,对于每个节点 v,我们将其左节点编号为 2 * v,将其右节点编号为 2 * v + 1

我们可以发现,树中所有节点的编号按照广度优先搜索顺序正好是升序。(也可以使用深度优先搜索,之后对序列排序)。

然后,我们检测编号序列是否为无间隔的 1, 2, 3, …,事实上,我们只需要检查最后一个编号是否正确,因为最后一个编号的值最大。

[]
class Solution { public boolean isCompleteTree(TreeNode root) { List<ANode> nodes = new ArrayList(); nodes.add(new ANode(root, 1)); int i = 0; while (i < nodes.size()) { ANode anode = nodes.get(i++); if (anode.node != null) { nodes.add(new ANode(anode.node.left, anode.code * 2)); nodes.add(new ANode(anode.node.right, anode.code * 2 + 1)); } } return nodes.get(i-1).code == nodes.size(); } } class ANode { // Annotated Node TreeNode node; int code; ANode(TreeNode node, int code) { this.node = node; this.code = code; } }
[]
class Solution(object): def isCompleteTree(self, root): 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] == len(nodes)

复杂度分析

  • 时间复杂度:$O(N)$,其中 $N$ 是树节点个数。
  • 空间复杂度:$O(N)$。

统计信息

通过次数 提交次数 AC比率
27012 50248 53.8%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言
上一篇:
957-N 天后的牢房(Prison Cells After N Days)
下一篇:
960-删列造序 III(Delete Columns to Make Sorted III)
本文目录
本文目录