一起穿过两棵树?

时间:2012-02-22 04:24:36

标签: algorithm

我正在寻找很多面试问题,其中问题需要一起穿越两棵树,我不确定如何去做这件事。

e.g。

  

鉴于对两个二叉树的根的引用,您如何确定   叶元素的顺序是否相等,但你必须   当第一个节点违反时,实现短路返回   规则。

4 个答案:

答案 0 :(得分:3)

您的问题是否要求了解是否: “通过访问2棵树的所有叶节点创建的序列是相同的”

有一个约束条件,当发现叶子值不匹配时,我们必须立即退出。

如果是这样,我建议采取以下解决方案:

insert (root of tree1) in stack1
insert (root of tree2) in stack2

temp1 = (root of tree1) -> left child
temp2 = (root of tree2) -> left child

while(stack1 and stack2 arent empty) 
{
    found = false
    while(found == false) {
        if (temp1 is leaf node)
            child1 = value of temp1
            found = true
            pop element from stack1
            set temp1 to its right child

        if (temp1 has left child)
            put temp1 in stack1
            set temp1 to its left child
    }

    found = false
    while(found == false) {
        if (temp2 is leaf node)
            child2 = value of temp2
            found = true
            pop element from stack2
            set temp2 to its right child

        if (temp2 has left child)
            put temp2 in stack2
            set temp2 to its left child
    }

    if(child1 != child2) 
        return
}

答案 1 :(得分:1)

一种可能的解决方案:

  • 我创建了一个树类,它有一个方法GetNextLeafNode()。它负责返回树的下一个直接叶节点。

  • 使用树类我保持堆栈以维护遍历的元素

  • 在GetNextLeafNode()方法中,我正在进行迭代树遍历(预订单)。

每当我遇到一个叶子节点(stack.Pop())时,我只是返回它。否则我将左右指针推到堆栈。最初推送根节点。在任何时候堆栈状态都是正确的。

以下是C#中的代码:

    public TreeNode GetNextLeafNode()
    {
        TreeNode leaf = null;

        while (s.Count != 0)
        {
            TreeNode n = s.Pop();
            if ((n.Left == null) && (n.Right == null))
            {
                leaf = n;
                return leaf;
            }
            else
            {
                if (n.Right != null)
                    s.Push(n.Right);
                if (n.Left != null)
                    s.Push(n.Left);
            }
        }

        return leaf;
    }

现在,我们可以创建两个不同的树,例如t1和t2。 我们可以按如下方式进行比较:

        int data1 = t1.GetNextLeafNode().Data;
        int data2 = t2.GetNextLeafNode().Data;

        while (data1 == data2)
        {
            //both the leaf nodes are same.
            data1 = t1.GetNextLeafNode().Data;
            data2 = t2.GetNextLeafNode().Data;
        }

答案 2 :(得分:0)

在伪代码中:

  1. 到每棵树的第一片叶子(让我们说最左边)。
  2. 进行比较。
  3. 如果不等于RETURN错误。
  4. 走到每棵树的下一片叶子里(直观地说 - 往上走,直到你看到一个走向正确孩子的方法,然后只带走左边的孩子,直到你到达一片叶子。)
  5. 如果其中一棵树有叶子但另一棵树返回根RETURN错误。
  6. 如果两棵树都返回root RETURN成功。
  7. 转到第2步。

答案 3 :(得分:0)

一个简单的python解决方案。 尽管这不是最佳空间,因为我们存储的叶子可以是O(N + M)。这不是同时迭代两个树。 时间复杂度-O(N + M)。

您还可以想到一种解决方案,其中空间以类似的方式为O(max(N,M))。

def binaryTreeLeafs(root1, root2):

    # The order in which we see leaves will
    # be maintained as it is inorder traversal.
    def dfs(node, leaves):
        if not node:
            return
        if not node.left and not node.right:
            leaves.append(node.val)
            return
        dfs(node.left, leaves)
        dfs(node.right, leaves)

    leaves1 = []
    leaves2 = []
    dfs(root1, leaves1)
    dfs(root2, leaves2)
    return leaves1 == leaves2


# O(h1+h2) space
def binaryTreeLeaves2(root1, root2):
    def isLeaf(node):
        return not node or node.left == node.right == None
    if not root1 and not root2:
        return True
    if (not root1) ^ (not root2):
        return False
    stack1 = [root1]
    stack2 = [root2]
    while stack1 or stack2:
        if (not stack1) ^ (not stack2):
            return False
        tmp1 = stack1.pop()
        while not isLeaf(tmp1):
            if tmp1.right:
                stack1.append(tmp1.right)
            if tmp1.left:
                stack1.append(tmp1.left)
            tmp1 = stack1.pop()
        tmp2 = stack2.pop()
        while not isLeaf(tmp2):
            if tmp2.right:
                stack2.append(tmp2.right)
            if tmp2.left:
                stack2.append(tmp2.left)
            tmp2 = stack2.pop()
        if ((not tmp1) ^ (not tmp2)) or (tmp1 and tmp2 and tmp1.val != tmp2.val):
            return False        
    return True