4.8 You have two very large binary trees: Tl, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of Tl. A tree T2 is a subtree of Tl if there exists a node n in Tl such that the subtree of n is identical to T2. That is, if you cut off the tree at node n, the two trees would be identical.

这道题给我们两棵树,T1和T2,其中T1有百万个节点,T2有上百个节点,让我们写算法来判断T2是不是T1的子树。首先可以用的方法是,我们对两棵树分别进行前序和中序遍历,然后把结果分别存入字符串中,如果T2的前序和中序遍历的字符串分别是T1的前序和中序遍历的字符串的子串,那么我们可以判定T2是T1的子树,参见代码如下:

解法一:

class Solution {
public:
bool containTree(TreeNode *root1, TreeNode *root2) {
string pre1, pre2, in1, in2;
preorder(root1, pre1);
preorder(root2, pre2);
inorder(root1, in1);
inorder(root2, in2);
if (pre1.find(pre2) == pre1.size() - pre2.size() && in1.find(in2) == in1.size() - in2.size()) return true;
else return false;
}
void preorder(TreeNode *root, string &res) {
if (!root) return;
res.append(to_string(root->val));
preorder(root->left, res);
preorder(root->right, res);
}
void inorder(TreeNode *root, string &res) {
if (!root) return;
inorder(root->left, res);
res.append(to_string(root->val));
inorder(root->right, res);
}
};

但是上面这种解法存在例外情况无法正确分辨,比如下面的两棵树:

3                       3

/           and            \

3                                 3

它们的中序和前序遍历都相同,所以上述算法会返回true,但我们知道它们是两个不同的树,谁也不包含谁,谁也不是谁的子树。Cracking the Coding Interview 5th Edition这书上第235页上说我们可以标记处空节点,但这种方法麻烦,又占空间,所以这里我不去写它。下面来看书上给出的另一种解法,这种解法的思路是,我们首先判断T2是否为空,为空则直接返回True,因为空树是任何树的子树,然后我们看T1是否为空,T1为空直接返回false,因为空树不可能有非空子树,然后我们看两个根节点的值是否相同,如果相同,则调用matchTree方法,来比较整个T2树,如果完全匹配则返回true,否则继续往下递归,参见代码如下:

解法二:

class Solution {
public:
bool containTree(TreeNode *root1, TreeNode *root2) {
if (!root2) return true;
if (!root1) return false;
if (root1->val == root2->val) {
if (matchTree(root1, root2)) return true;
}
return containTree(root1->left, root2) || containTree(root1->right, root2);
}
bool matchTree(TreeNode *root1, TreeNode *root2) {
if (!root1 && !root2) return true;
if (!root1 || !root2) return false;
if (root1->val != root2->val) return false;
else (matchTree(root1->left, root2->left) && matchTree(root1->right, root2->right));
}
};

[CareerCup] 4.8 Contain Tree 包含树的更多相关文章

  1. [转] Splay Tree(伸展树)

    好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集 ...

  2. 【数据结构】B-Tree, B+Tree, B*树介绍 转

    [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...

  3. B-Tree, B+Tree, B*树介绍

    [数据结构]B-Tree, B+Tree, B*树介绍 转   [数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是 ...

  4. 一步一步分析Gin框架路由源码及radix tree基数树

    Gin 简介 Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much ...

  5. Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)

    在目前的Mysql数据库中,使用最广泛的是innodb存储引擎.innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择.当然,这偏文 ...

  6. 页面设计--Tree目录树

    Tree目录树控件属性: 根据数据集合来配置相应的信息 加载模式有自动加载.自定加载 web中显示效果图:

  7. CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)

    CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...

  8. [Flex] 组件Tree系列 —— 运用LabelFunction hasChildren getChildren设置Tree包含节点个数

    mxml: <?xml version="1.0" encoding="utf-8"?> <!--功能描述:运用LabelFunction h ...

  9. poj 1741 Tree(树的点分治)

    poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...

随机推荐

  1. Swift面向对象基础(中)——Swift中的方法

    学习来自<极客学院> 1.定义方法需要在类型(枚举,结构体,类)里定义,不能独立定义,独立定义的是函数 2.方法要么属于该类型本身,要么是该类型的一个实例 3.不能独立执行方法,执行方法必 ...

  2. log4net资料收集

    Log4net 日志使用介绍 http://www.cnblogs.com/jys509/p/4699813.html log4net Tutorial http://www.codeproject. ...

  3. Effective Java 65 Don't ignore exceptions

    Principle An empty catch block defeats the purpose of exceptions, which is to force you to handle ex ...

  4. Java主要有那几种文件类型?各自的作用是什么

    1.源代码.java程序员编译的源代码. 2..class  字节码文件 jvm实现跨平台的中间编译文件. 3.jar包 讲字节码文件打包好,便于查找和使用.

  5. 详解Winform里面的缓存使用

    缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.本文主要针对自己在Winform方面的缓存使用做一个引导性的介绍,希望大家能够从中了解一些缓存 ...

  6. 问题解决——在STL的queue中使用自定义类

    本文原创,转载请保证文章的完整性,并显要的注明出处. 本文链接:http://blog.csdn.net/wlsgzl/article/details/38843513 平时很少用STL,就算用,也基 ...

  7. python strip() lstrip() rstrip() 使用方法

    Python中的strip用于去除字符串的首尾字符串,同理,lstrip用于去除最左边的字符,rstrip用于去除最右边的字符. 这三个函数都可传入一个参数,指定要去除的首尾字符. 需要注意的是,传入 ...

  8. CANopen DS301协议中文翻译V03版

    V0.1版PDF格式供下载参考,只是全面框架翻译,会有大量错误和不确定的地方,希望读者积极参与校对,提供修改意见,完善译文.下载 V0.2版校对提前完成,下载地址 V0.3版使用GitBook编辑(h ...

  9. 第22章 DLL注入和API拦截(1)

    22.1 注入的一个例子(跨进程子类化窗口) ①子类化窗口可以改变窗口的行为,让发往该窗口的消息重新发到我们指定的过程来处理.但这种行为只能在本进程中(如A),对于从一个进程(如B)去子类化另一个进程 ...

  10. java 20 - 4 IO流概述和一个简单例子解析

    IO流的分类:  流向: 输入流 读取数据  输出流 写出数据 数据类型:  字节流  字节输入流 读取数据 InputStream  字节输出流 写出数据 OutputStream  字符流  字符 ...