• LeetCode222. 完全二叉树的节点个数


    背景知识:

      完全二叉树:除了最后一层,所有层的节点数达到最大,与此同时,最后一层的所有节点都在最左侧。(堆使用完全二叉树)

      满二叉树:所有层的节点数达到最大。一棵层数为 h 的满二叉树,其节点数为2^h - 1个。

    思路1:层序遍历 或 递归 遍历整棵树。 但没用到 完全二叉树 的性质。。不可取

    思路2:左神P178 ,        时间复杂度为O(h^2), h为完全二叉树的层数

      知识点1:层数为h的满二叉树的节点数为2^h - 1个

      知识点2:完全二叉树的高度可以直接通过不断地访问左子树就可以获取

    具体步骤为:

      (1)如果不是空树,求完全二叉树的高度。求法是找到树的最左节点看能到哪一层,层数记为h

      (2)递归函数 bs(node, l ,h)的返回值表示以node为头的完全二叉树的节点数是多少。l表示node所在的层数,h表示整棵树的层数是始终不变的。初始时,node为头节点head, l 为 1

      找到node右子树的最左节点,如果能到达最后一层,见(2.1),如果不能,见(2.2)

        (2.1)第一种情况:说明node的整棵左子树是满二叉树,并且层数为h-l 。 node的整棵左子树再加上node本身,节点数为2^(h-l)-1+1. 此时再递归求出node右子树的节点数即可。 bs(node.right, l + 1, h) 。 因此,整体为2^(h-l)+bs(node.right, l + 1, h)

        (2.2)第二种情况:说明node的整棵右子树是满二叉树,层数为h-l-1. 同(2.1),整体为2^(h - l - 1) -1 + 1+bs(node.left, l + 1, h)

      (3)复杂度分析。 每一层只会选择一个节点node进行bs的递归过程,所以调用bs函数的次数为O(h)

               每次调用bs函数时,都会查看node右子树的左子节点,所以会遍历O(h)个节点,因此总的复杂度为O(h^2)

    class Solution {
        public int countNodes(TreeNode root) {
            if (root == null) return 0;
            return bs(root, 1, mostLeftLevel(root, 1));
        }
        
        // 返回以node为根的完全二叉树的节点数是多少
        private int bs(TreeNode node, int curLevel, int level) {
            if (curLevel == level) {
                return 1;
            }
            // 对应情况2.1
            if (mostLeftLevel(node.right, curLevel + 1) == level) {
    //            return (int)Math.pow(2,level - curLevel) + bs(node.right, curLevel + 1, level);
                return (1 << (level - curLevel)) + bs(node.right, curLevel + 1, level);
            }else { // 对应情况2.2
    //            return (int)Math.pow(2,level - 1 - curLevel) + bs(node.left, curLevel + 1, level);
                return (1 << (level - 1 - curLevel)) + bs(node.left, curLevel + 1, level);
            }
        }
        
        // 求出以node为根的树的最左节点的层数
        private int mostLeftLevel(TreeNode node, int start) {
            while (node != null) {
                node = node.left;
                start ++;
            }
            return start - 1;
        }
    }
  • 相关阅读:
    [置顶] 搭建一个流媒体服务器引子
    Exchange Server 2007 常见问题解答(6)
    [置顶] 第九周项目1
    iOS 6应用开发实战
    hdu 1722(数论)
    js二维数组排序
    HDU 4027 线段树 Can you answer these queries?
    Socket编程指南及示例程序
    Spring攻略学习笔记(2.13)解析文本消息
    线性渐变lineargradient和滤镜opacity/filter的透明效果兼容性解决方案及其RGB/RGBA与16进制转换方法
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/14171735.html
Copyright © 2020-2023  润新知