zoukankan      html  css  js  c++  java
  • [LeetCode] Subtree of Another Tree 另一个树的子树

    Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree scould also be considered as a subtree of itself.

    Example 1:
    Given tree s:

         3
        / 
       4   5
      / 
     1   2
    

    Given tree t:

       4 
      / 
     1   2
    

    Return true, because t has the same structure and node values with a subtree of s.

    Example 2:
    Given tree s:

         3
        / 
       4   5
      / 
     1   2
        /
       0
    

    Given tree t:

       4
      / 
     1   2
    

    Return false.

    这道题让我们求一个数是否是另一个树的子树,从题目中的第二个例子中可以看出,子树必须是从叶结点开始的,中间某个部分的不能算是子树,那么我们转换一下思路,是不是从s的某个结点开始,跟t的所有结构都一样,那么问题就转换成了判断两棵树是否相同,也就是Same Tree的问题了,这点想通了其实代码就很好写了,用递归来写十分的简洁,我们先从s的根结点开始,跟t比较,如果两棵树完全相同,那么返回true,否则就分别对s的左子结点和右子结点调用递归再次来判断是否相同,只要有一个返回true了,就表示可以找得到。

    解法一:

    class Solution {
    public:
        bool isSubtree(TreeNode* s, TreeNode* t) {
            if (!s) return false;
            if (isSame(s, t)) return true;
            return isSubtree(s->left, t) || isSubtree(s->right, t);
        }
        bool isSame(TreeNode* s, TreeNode* t) {
            if (!s && !t) return true;
            if (!s || !t) return false;
            if (s->val != t->val) return false;
            return isSame(s->left, t->left) && isSame(s->right, t->right);
        }
    };

    下面这道题的解法用到了之前那道Serialize and Deserialize Binary Tree的解法,思路是对s和t两棵树分别进行序列化,各生成一个字符串,如果t的字符串是s的子串的话,就说明t是s的子树,但是需要注意的是,为了避免出现[12], [2], 这种情况,虽然2也是12的子串,但是[2]却不是[12]的子树,所以我们再序列化的时候要特殊处理一下,就是在每个结点值前面都加上一个字符,比如',',来分隔开,那么[12]序列化后就是",12,#",而[2]序列化之后就是",2,#",这样就可以完美的解决之前的问题了,参见代码如下:

    解法二:

    class Solution {
    public:
        bool isSubtree(TreeNode* s, TreeNode* t) {
            ostringstream os1, os2;
            serialize(s, os1);
            serialize(t, os2);
            return os1.str().find(os2.str()) != string::npos;
        }
        void serialize(TreeNode* node, ostringstream& os) {
            if (!node) os << ",#";
            else {
                os << "," << node->val;
                serialize(node->left, os);
                serialize(node->right, os);
            }
        }
    };

    类似题目:

    Count Univalue Subtrees 

    Most Frequent Subtree Sum

    Serialize and Deserialize Binary Tree

    Same Tree

    参考资料:

    https://discuss.leetcode.com/topic/88508/java-solution-tree-traversal

    https://discuss.leetcode.com/topic/88491/java-concise-o-n-m-time-o-n-m-space

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

    LeetCode All in One 题目讲解汇总(持续更新中...)

  • 相关阅读:
    C#Redis哈希Hashes
    C#Redis集合set
    C#Redis列表List
    C#Redis字符串
    入门redis
    C#/Net代码精简优化技巧
    单点登录在asp.net中的简单实现
    sql注入
    数据库sql优化
    常常忘记但是很重要的sql语句
  • 原文地址:https://www.cnblogs.com/grandyang/p/6828687.html
Copyright © 2011-2022 走看看