题目链接

LeetCode

题目描述

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

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

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

示例 1:

958. 二叉树的完全性检验** - 图1

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

示例 2:

958. 二叉树的完全性检验** - 图2

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

解题思路

方法一:广度优先搜索

什么时候是不完全呢?其实就是出现null结点之后后面又出现了结点,如果是完全则最后一个null结点之后就结束遍历了

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. bool isCompleteTree(TreeNode* root) {
  15. // 层序遍历的辅助利器
  16. queue<TreeNode*> q;
  17. // 记录是否已经遍历到null结果
  18. bool reachNull = false;
  19. q.push(root);
  20. while (!q.empty()){
  21. TreeNode* curr = q.front();
  22. q.pop();
  23. if (curr == nullptr){
  24. // 发现空结点了
  25. reachNull = true;
  26. continue;
  27. }else{
  28. // 发现null结点后出现非空结点,发现不完全了
  29. if (reachNull){
  30. return false;
  31. }
  32. // 继续遍历左右节点
  33. q.push(curr->left);
  34. q.push(curr->right);
  35. }
  36. }
  37. return true;
  38. }
  39. };
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isCompleteTree(TreeNode root) {
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(root);
        boolean searchNull = false; // 遇到null了吗
        while(!q.isEmpty()){
            TreeNode node = q.poll();
            if(node == null){
                searchNull = true;
            }else{
                if(searchNull){
                    return false;
                }
                q.offer(node.left);
                q.offer(node.right);
            }
        }
        return true;
    }
}
  • 时间复杂度 O(n)
  • 空间复杂度 O(2^k)

    方法二:数组

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isCompleteTree(TreeNode root) {
        List<TreeNode> lst = new ArrayList<TreeNode>();
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(root);
        while(!q.isEmpty()){
            TreeNode node = q.poll();
            if(node != null){
                q.offer(node.left);
                q.offer(node.right);
            }
            lst.add(node);
        }
        int i = 0;
        while(i < lst.size()){
            if(lst.get(i) == null || lst.get(2*i + 1) == null || lst.get(2*i + 2) == null){
                if(lst.get(i) == null){
                    break;
                }else if(lst.get(2*i + 1) == null){
                    i = 2*i + 1;
                }else{
                    i = 2*i + 2;
                }
                break;
            }
            ++i;
        }
        while(i < lst.size()){
            if(lst.get(i++) != null){
                return false;
            }
        }
        return true;
    }
}