剑指Offer_编程题——树的子结构
题目描述:
输入两棵二叉树A,B ,判断B是不是A的子结构。主意:我们约定空树不是任意一颗树的 子结构
具体要求:
时间限制: C/C++ 1秒,其他语言2秒
空间限制: C/C++32M,其他语言64M
具体思路:
对于二叉树来说遍历的时候最好是利用递归的方法。
1、首先设置标志位result = false,因为一旦匹配成功result就设为true。剩下的代码不会被执行。如果匹配不成功,默认返回false
2、利用递归的思想:如果根节点相同则递归调用DoesTree1HaveTree2(),如果根节点不同,则判断tree1的左子树和tree2是否相同,再判断右子树是否和tree2相同
3、注意null的条件,在HasSubTree中,如果两棵树都不为空才进行判断,DoesTree1HaveTree2中,如果Tree2为空,则说明第二棵树遍历完了,则匹配成功。
当然tree1为空有两种情况:
① 如果tree1为空 && tree2不为空说明不匹配。
② 如果tree1为空 && tree2也为空,说明匹配。
具体用Java实现该思路如下:
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result = false;
if(root2 != null && root1 != null){
if(root1.val == root2.val)
result = doesTree1HaveTree2(root1, root2);
if (!result)
result = HasSubtree(root1.left, root2);
if(!result)
result = HasSubtree(root1.right, root2);
}
return result;
}
public static boolean doesTree1HaveTree2(TreeNode node1, TreeNode node2){
if(node2 == null)
return true;
if(node1 == null)
return false;
if(node1.val != node2.val)
return false;
return doesTree1HaveTree2(node1.left, node2.left) && doesTree1HaveTree2(node1.right, node2.right);
}
}
代码效果图如图所示:
正如前面提到一样,牛客网已经为我们定义了节点,不需要我们重复定义,但是在自己的本地编译器中,我们需要定义节点TreeNode的类,具体实现如下:
public class TreeNode{
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val){
this.val = val;
}
}
具体用python实现:
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
# write code here
if not pRoot1 or not pRoot2:
return False
return self.is_subtree(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2)
def is_subtree(self, A, B):
if not B:
return True
if not A or A.val != B.val:
return False
return self.is_subtree(A.left,B.left) and self.is_subtree(A.right, B.right)
代码效果图如图所示:
用python实现树结构:
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
总结
本道题主要考察树的子结构,通过定义一个树的结构,利用递归来进行二叉树的遍历,不过需要注意的是:tree1为空的两种情况,如果在tree1为空的同时tree2也为空,即匹配成功。否则匹配失败。在数据结构中,树的实现就比较难了,不过应用也是挺广的。因此我们要熟悉掌握这块的知识点。总之,我们要继续加油,争取早日找到工作,Good Luck!!!