"统计完整的树节点" - 如何优化解决方案?

时间:2015-10-16 10:23:24

标签: java algorithm data-structures tree binary-tree

我已经为这个问题写了一个解决方案: https://leetcode.com/problems/count-complete-tree-nodes/
但我得到了TLE。我该如何优化它?

public class Solution 
{
    public int countNodes(TreeNode root) 
    {
        if(root==null)
            return 0;
        int left = count(root.left);
        int right = count(root.right);
        if(left<=right)
        {
            return ((int)(Math.pow(2, left)-1) + countNodes(root.right) + 1);
        }
        else
        {
            return (countNodes(root.left) + (int)(Math.pow(2, right)-1) + 1);
        }
    }

    public static int count(TreeNode root)
    {
        int ctr=0;
        while(root!=null)
        {
            ctr++;
            root = root.left;
        }
        return ctr;
    }
}

树在OJ中被定义为:

/**
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

3 个答案:

答案 0 :(得分:1)

我接受的解决方案:

public class Solution {
    public int countNodes(TreeNode root) {
        if(root == null){
            return 0;
        }
        int h = 0;
        TreeNode node = root;
        while(node != null){
            h++;
            node = node.left;
        }
        return count(h, root);
    }

    public int count(int h, TreeNode node){
        if(node == null){
            return 0;
        }
        int v = heightRight(node.left);
        if(v == h - 1){
            return  (1 << (h - 1)) + count(h - 1, node.right);
            //The left subtree is a perfect binary tree with height h - 1
            //So, we only need to look at the right subtree
        }else {
            return (1 << (h - 2)) + count(h - 1, node.left);
            //The right subtree is perfect binary tree with height h - 2
            //So, we only need to look at the left subtree
        }
    }

    public int heightRight(TreeNode node){
        if(node == null){
            return 0;
        }
        int result = 0;
        while(node != null){
            node = node.right;
            result++;
        }
        return result;
    }
}

因此,我们可以通过应用类似二元搜索的技术来解决这个问题。

由于完整的二叉树搜索树几乎是完美的二叉树,除了最后一级,所以,

如果树的高度为h,则左子树的高度为h - 1,右子树的高度为[h - 2,h - 1]。

- &GT;我们需要做的是找到高度为h-2的最左边的节点。

答案 1 :(得分:0)

让我告诉你思考的方法。

首先,我们定义countLevel(TreeNode tree) - return the level of the binary tree

我们这样做:

countLevel(TreeNode tree):
  if (tree.isNoChild()) 
    return 1;
  else 
    return countLevel(tree.left) + 1;
  // countLevel(tree.right) always less than or equals countLevel(tree.left) in complete binary tree

如果我们知道级别为i,那么我们就知道节点数在[2^(i-1), 2^i - 1]之间。

在我们尝试解决原点问题之后,我们首先解决一个更容易的问题:

isNodesMoreThan(TreeNode tree, int n) - does tree have n nodes or more?

您应该尝试解决此问题,并且可以在log(n)中完成(n是输入树的节点数)。

如果您解决了isNodesMoreThan,并且通过二分搜索,您可以获得log(n)*log(n)中不会获得TLE的树的节点数。

答案 2 :(得分:0)

似乎(int)(Math.pow(2, left)-1)(int)(Math.pow(2, right)-1)太慢了。只需将它们更改为

即可
(1 << left) - 1
(1 << right) - 1

并且您将接受您的代码。