【问题标题】:"Count Complete Tree Nodes" - How to optimize the solution?“计算完整的树节点” - 如何优化解决方案?
【发布时间】:2015-10-16 10:23:24
【问题描述】:

我已经为这个问题写了一个解决方案: 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; }
 * }
 */

【问题讨论】:

  • 本站用于解决开发过程中出现的错误。你的问题更适合Code Review
  • 在静态 count() 方法中,您只计算左侧的节点而不是右侧的节点。作为完整性的一部分,您可能会错过正确计数。
  • @GeraldSchneider 我不知道那个网站。我一定会在未来发布相应的内容。
  • @a3.14_Infinity 我故意这样做的。问题陈述中提到“最后一层的所有节点都尽量靠左”。因此,不会出现特定节点有右孩子但没有左孩子的情况。反过来也是可能的。

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


【解决方案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]之间。

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

【讨论】:

  • 又一个log(n)*log(n) 解决方案,但比我的短。
【解决方案2】:

让我告诉你思考的方式。

首先,我们定义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。

【讨论】:

    【解决方案3】:

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

    (1 << left) - 1
    (1 << right) - 1
    

    您的代码将被接受。

    【讨论】:

      猜你喜欢
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      相关资源
      最近更新 更多