递归BinaryTree遍历的RunTime复杂性

时间:2017-06-24 19:09:24

标签: algorithm recursion time-complexity binary-tree big-o

这是我对problem的解决方案,在给定二叉树的情况下,您要求查找所有非直接链接节点的总和。 "直接链接"是指亲子关系,只是为了清楚。

我的解决方案 如果访问了当前节点,则不允许您访问下一级别的节点。但是,如果未访问当前节点,则可能会访问或不访问下一级别的节点。

它通过了所有测试。但是,此递归二叉树遍历的运行时复杂性是什么。我认为它是2^n因为,在每个节点,你有两个选择,无论是使用它还是不使用它,因此,下一个级别,对于这些选择中的每一个都有两个选择,等等。

空间复杂性:不使用任何额外的空间进行存储,但由于这是一个递归实现,因此使用堆栈空间,堆栈中的最大元素可以是树的高度,即n。所以O(n)

public int rob(TreeNode root) {
        return rob(root, false);
    }

    public int rob(TreeNode root, boolean previousStateUsed) {

        if(root == null)
            return 0;

        if(root.left == null && root.right == null)
        {
            if(previousStateUsed == true)
                return 0;
            return root.val;
        }

        if(previousStateUsed == true)
        {
            int leftSumIfCurrentIsNotUsedNotUsed = rob(root.left, false);
            int rightSumIfCurrentIsNotUsed = rob(root.right, false);
            return leftSumIfCurrentIsNotUsedNotUsed + rightSumIfCurrentIsNotUsed;
        }
        else
        {
            int leftSumIfCurrentIsNotUsedNotUsed = rob(root.left, false);
            int rightSumIfCurrentIsNotUsed = rob(root.right, false);
            int leftSumIsCurrentIsUsed = rob(root.left, true); 
            int rightSumIfCurrentIsUsed = rob(root.right, true);
            return Math.max(leftSumIfCurrentIsNotUsedNotUsed + rightSumIfCurrentIsNotUsed, leftSumIsCurrentIsUsed + rightSumIfCurrentIsUsed + root.val);
        }

    }

1 个答案:

答案 0 :(得分:1)

您当前的递归解决方案是O(2^n)。很清楚,看看我们是否举了一个例子:

tree

接下来,让我们划掉交替的节点层:

tree-crossed

对于剩余的节点,我们有大约n/2个节点(这会有所不同,但您总是可以删除交替的层以获得至少n/2 - 1个节点的最坏情况。只有这些节点,我们可以将它们组合在一起,因为它们都没有冲突。因此,我们可以确定这至少需要Omega( 2^(n/2) )次最坏情况。您可能会受到更严格的限制,但这应该会让您意识到您的解决方案无法很好地扩展。

这个问题是Max Non-Adajacent Sum Problem的常见修改。

您应该能够在此使用动态编程。我会极力推荐它。想象一下,我们正在为节点i找到解决方案。假设我们已经有节点i.lefti.right的解决方案,我们也假设我们有他们的孩子(i的孙子女)的解决方案。我们现在有i最大解决方案的两个选项:

  • max-sum(i.left) + max-sum(i.right)

  • i.val + max-sum(i.left.left) + max-sum(i.left.right) + max-sum(i.right.left) + max-sum(i.right.right)

您最多使用这些,这是i的解决方案。您可以在当前程序中执行此自下而上的DP或使用memoization。要么应该工作。最好的部分是,现在您的解决方案是O(n)