leetcode -- 222. Count Complete Tree Nodes【子问题划分】

题目

Given a complete binary tree, count the number of nodes.

Definition of a complete binary tree from Wikipedia:
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.


题意

给定一个完全二叉树,数其有多少个结点。(注意完全二叉树的定义)



分析及解答

注意的问题:

普通的方法,一个一个去数几点的方法是行不通的,因为时间的限制,时间复杂度太高了。

方法1(完全二叉树性质):

树的高度可以通过一直向左来确定。我们这里设定单节点树的高度为0.然后我们会发现高度为 h的整棵树。如果整棵树是空的,那么让height-1,有0个结点。

否则检查右子树的高度是否是否只是比整棵树的高度少1,是则意味着左右子树有相同的高度。

  • 如果是,那么最后一行的的最后一个结点在右子树中,这意味着左子树是高度为h-1的满树。所以我们我们可以确定左子树的2^h-1个结点,加上1个根节点,再加上右子树递归处理后的结果
  • 如果否,那么最后一行的最后一个结点在左子树中,这意味着右子树是满的,高度为 h-2。所以我们使得右子树的数量2^(h-1)+1个结点,加上1个根节点,再加上左子树递归处理后的结果

因为我们递归处理的这棵树,所以我们有O(log(n))步,找到高度需要花费O(log(n))。所以时间复杂度为O(log(n)^2)。

class Solution {
    int height(TreeNode root) {
        return root == null ? -1 : 1 + height(root.left);
    }
    public int countNodes(TreeNode root) {
        int h = height(root);
        return h < 0 ? 0 :
               height(root.right) == h-1 ? (1 << h) + countNodes(root.right)
                                         : (1 << h-1) + countNodes(root.left);
    }
}

迭代版本

这是迭代版本,我不需要每步重新计算h。

class Solution {
    int height(TreeNode root) {
        return root == null ? -1 : 1 + height(root.left);
    }
    public int countNodes(TreeNode root) {
        int nodes = 0, h = height(root);
        while (root != null) {
            if (height(root.right) == h - 1) {
                nodes += 1 << h;
                root = root.right;
            } else {
                nodes += 1 << h-1;
                root = root.left;
            }
            h--;
        }
        return nodes;
    }
}


原文地址:

https://discuss.leetcode.com/topic/15533/concise-java-solutions-o-log-n-2/2

你可能感兴趣的:(算法练手)