使用预先遍历遍历和字符串方法来展平二叉树以查找子树?

时间:2017-09-21 01:21:20

标签: algorithm binary-tree tree-traversal

最近,我遇到了这个解决方案,用于查找提供的树是否是更大树的子树:

https://discuss.leetcode.com/topic/88700/easy-o-n-java-solution-using-preorder-traversal

解决方案非常直观且富有创意,所以我为自己的启发实现了它的递归版本;但我发现自己想知道为什么同样的解决方案不能用于订购后或订购。

这是我尝试通过所有LeetCode测试用例的C ++解决方案:

class Solution {
public:
    std::string s1;
    std::string s2;

    void generatePreOrder(TreeNode *root, std::string &s)
    {
       if (root == 0)
       {
           s+=std::string(",#");
           return;
       }
       s+=std::string(",");
       s+=std::string(std::to_string(root->val));
       generatePreOrder(root->left, s);
       generatePreOrder(root->right, s);
    }
    bool isSubtree(TreeNode* s, TreeNode* t) {
        generatePreOrder(s, s1);
        generatePreOrder(t, s2);
        int pos = s1.find(s2);
        return (!(pos == std::string::npos));
    }
};

从根本上说,似乎我们只是将树扁平化为字符串并使用字符串比较函数来查找树之间的相似性。所以,我想,只要两棵树之间的排序一致,三种排序方案中的任何一种都应该可以正常工作。但是,当我更改解决方案以使其按顺序执行时:

 ...
    void generateInOrder(TreeNode *root, std::string &s)
    {
       if (root == 0)
       {
           s+=std::string(",#");
           return;
       }
       generateInOrder(root->left, s);
       s+=std::string(",");
       s+=std::string(std::to_string(root->val));
       generateInOrder(root->right, s);
    }
 ...

该解决方案无法通过所有LeetCode案例。这是因为预先订购这种方法有天生的东西吗?或者它只是LeetCode运动机制中的一个洞,整个方法都存在缺陷?

1 个答案:

答案 0 :(得分:0)

当您包含空值时,每个形状不同的树都会生成唯一的预订或后序遍历。

对于顺序遍历不是这样,它总是以null开头,以null结尾,并在空值和节点之间交替。

,例如,这些树木:

  B          D    
 / \        / \
A   D      B   E
   / \    / \
  C   E  A   C

都产生

,#,A,#,B,#,C,#,D,#,E,#