1

以下程序返回树是否平衡。如果从根到任何叶子的路径具有相同的长度,则称一棵树是平衡的。

using System;
namespace BalancedTree
{
public class MainClass 
{
    static bool isBalanced(int[][] sons) 
    {
        return isBalanced(sons, 0);
    }

    static bool isBalanced(int[][] sons, int startNode) 
    {
        int[] children = sons[startNode];

        int minHeight = int.MaxValue;
        int maxHeight = int.MinValue;

        bool allChildBalanced = true;

        if(children.Length == 0)
                return true;
        else 
        {
            foreach (int node in children) 
            {
                int h = height(sons, node);
                if(h > maxHeight)
                    maxHeight = h;

                if(h < minHeight)
                    minHeight = h;  
            }
        }
        foreach (int node in children) 
        {
            allChildBalanced = allChildBalanced && isBalanced(sons, node);

            if(!allChildBalanced)
                return false;
        }
        return Math.Abs(maxHeight - minHeight) < 2 && allChildBalanced;
    }

    static int height(int[][] sons, int startNode) 
    {
        int maxHeight = 0;

        foreach (int child in sons[startNode]) 
        {
            int thisHeight = height(sons, child);
            if(thisHeight > maxHeight) 
                maxHeight = thisHeight;
        }
        return 1 + maxHeight;
    }

    public static void Main (string[] args) 
    {
        int[][] sons = new int[6][];

        sons[0] = new int[] { 1, 2, 4 };
        sons[1] = new int[] { };
        sons[2] = new int[] { 3, 5};
        sons[3] = new int[] { };
        sons[4] = new int[] { };
        sons[5] = new int[] { };

        Console.WriteLine (isBalanced(sons));
    }

}
}

我的问题是我的代码效率很低,因为递归调用函数

static int height(int[][] sons, int startNode)

使时间复杂度成指数级。我知道这可以在二叉树的情况下进行优化,但我正在寻找一种方法来优化我的程序,以防上面描述的一般树。例如,一种想法是从当前节点而不是 startNode 调用函数“height”。我唯一的限制是时间复杂度必须是线性的,但我可以使用额外的内存。

4

1 回答 1

1

对不起,但我从来没有做过 C#。因此,不会有示例代码。

但是,您应该不会太难做到这一点。

递归定义 isBalanced() 永远不会提供最佳性能。原因很简单:如果所有子树都是平衡的,那么一棵树仍然可能是不平衡的。所以,你不能只遍历树一次。

但是,您的 height() 函数已经做了正确的事情。它只访问树中的每个节点一次以找到高度(即从根到叶的最大长度)。

您所要做的就是编写一个 minDistance() 函数来找到从根到叶的最小长度。您可以使用几乎相同的代码来执行此操作。

使用这些函数,当且仅当 height(...)==minDistance(...) 时,树是平衡的。

最后,您可以将这两个函数合并为一个返回 (min,max) 对的函数。这不会改变时间复杂度,但可能会稍微缩短执行时间,如果在 C# 中返回对不是太贵的话

于 2018-05-16T18:38:42.903 回答