【问题标题】:RunTime Complexity of Recursive BinaryTree Traversal递归二叉树遍历的运行时复杂度
【发布时间】:2017-11-28 03:07:44
【问题描述】:

这是我对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);
        }

    }

【问题讨论】:

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


    【解决方案1】:

    您当前的递归解决方案是O(2^n)。举个例子就很清楚了:

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

    对于剩余的节点,我们大约有 n/2 节点(这会有所不同,但您始终可以删除交替层以获得至少 n/2 - 1 节点最坏的情况)。仅使用这些节点,我们就可以对它们进行任意组合,因为它们都不冲突。因此,我们可以确定这至少需要Omega( 2^(n/2) ) 时间最坏的情况。您可能可以获得更严格的界限,但这应该会让您意识到您的解决方案无法很好地扩展。

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

    您应该能够对此使用动态编程。我会极力推荐它。想象一下,我们正在寻找节点i 的解决方案。假设我们已经有了节点i.left 和i.right 的解决方案,并且我们还假设我们有他们的孩子(i 的孙子)的解决方案。对于i 的最大解决方案,我们现在有 2 个选项:

    • 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)!

    【讨论】:

    • 谢谢。对于 DP,您的意思是说,在您的回复的最后一行中,时间复杂度是 O(n) 或 O(n!)。我要去 O(n)。
    • @PepperBoy,是的O(n)。我只是热情地说:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    相关资源
    最近更新 更多