【剑指Offer学习】【面试题18 :树的子结构】
题目:输入两棵二叉树A 和B。推断B 是不是A 的子结构。
二叉树结点的定义:
/**
* 二叉树的树结点
*/
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
}
解题思路:
要查找树A 中是否存在和树B 结构一样的子树。我们能够分成两步: 第一步在树A 中找到和B 的根结点的值一样的结点R。 第二步再推断树A 中以R 为根结点的子树是不是包括和树B 一样的结构。
代码实现
public class Test18 {
/**
* 二叉树的树结点
*/
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
}
/**
* 输入两棵二叉树A和B,推断B是不是A的子结构。
* 该方法是在A树中找到一个与B树的根节点相等的元素的结点。
* 从这个相等的结点開始推断树B是不是树A的子结构,假设找到其的一个就返回,
* 否则直到全部的结点都找完为止。
*
* @param root1 树A的根结点
* @param root2 树B的根结点
* @return true:树B是树A的子结构,false:树B是不树A的子结构
*/
public static boolean hasSubtree(BinaryTreeNode root1, BinaryTreeNode root2) {
// 仅仅要两个对象是同一个就返回true
// 【注意此处与书本上的不同,书本上的没有这一步】
if (root1 == root2) {
return true;
}
// 仅仅要树B的根结点点为空就返回true
if (root2 == null) {
return true;
}
// 树B的根结点不为空。假设树A的根结点为空就返回false
if (root1 == null) {
return false;
}
// 记录匹配结果
boolean result = false;
// 假设结点的值相等就,调用匹配方法
if (root1.value == root2.value) {
result = match(root1, root2);
}
// 假设匹配就直接返回结果
if (result) {
return true;
}
// 假设不匹配就找树A的左子结点和右子结点进行推断
return hasSubtree(root1.left, root2) || hasSubtree(root1.right, root2);
}
/**
* 从树A根结点root1和树B根结点root2開始。一个一个元素进行推断。推断B是不是A的子结构
*
* @param root1 树A開始匹配的根结点
* @param root2 树B開始匹配的根结点
* @return 树B是树A的子结构。false:树B是不树A的子结构
*/
public static boolean match(BinaryTreeNode root1, BinaryTreeNode root2) {
// 仅仅要两个对象是同一个就返回true
if (root1 == root2) {
return true;
}
// 仅仅要树B的根结点点为空就返回true
if (root2 == null) {
return true;
}
// 树B的根结点不为空。假设树A的根结点为空就返回false
if (root1 == null) {
return false;
}
// 假设两个结点的值相等,则分别推断其左子结点和右子结点
if (root1.value == root2.value) {
return match(root1.left, root2.left) && match(root1.right, root2.right);
}
// 结点值不相等返回false
return false;
}
public static void main(String[] args) {
BinaryTreeNode root1 = new BinaryTreeNode();
root1.value = 8;
root1.right = new BinaryTreeNode();
root1.right.value = 7;
root1.left = new BinaryTreeNode();
root1.left.value = 8;
root1.left.left = new BinaryTreeNode();
root1.left.left.value = 9;
root1.left.right = new BinaryTreeNode();
root1.left.right.value = 2;
root1.left.right.left = new BinaryTreeNode();
root1.left.right.left.left = new BinaryTreeNode();
root1.left.right.left.left.value = 4;
root1.left.right.left.right = new BinaryTreeNode();
root1.left.right.left.right.value = 7;
BinaryTreeNode root2 = new BinaryTreeNode();
root2.value = 8;
root2.left = new BinaryTreeNode();
root2.left.value = 9;
root2.right = new BinaryTreeNode();
root2.right.value = 2;
System.out.println(hasSubtree(root1, root2));
System.out.println(hasSubtree(root2, root1));
System.out.println(hasSubtree(root1, root1.left));
System.out.println(hasSubtree(root1, null));
System.out.println(hasSubtree(null, root2));
System.out.println(hasSubtree(null, null));
}
}
执行结果
输入的树:
输出结果:
【剑指Offer学习】【面试题18 :树的子结构】的更多相关文章
- 《剑指offer》面试题18 树的子结构 Java版
(输入两棵二叉树A和B,判断B是不是A的子结构.补充下,根据书中的代码来看,子结构的定义并不包括叶子节点下的null,也就是说只要B的存在数字的结构存在于A中就行,那么如果B是null树,那么就不属于 ...
- 【剑指Offer】面试题26. 树的子结构
题目 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A: 3 / \ ...
- 《剑指offer》面试题26. 树的子结构
问题描述 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A: 3 / ...
- 剑指Offer(十七):树的子结构
剑指Offer(十七):树的子结构 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_ ...
- 【剑指offer】面试题 18. 删除链表的节点
面试题 18. 删除链表的节点
- 剑指Offer(书):树的子结构
题目:输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 分析:关于二叉树大部分适应于递归结构. public boolean HasSubtree(TreeN ...
- (剑指Offer)面试题18:树的子结构
题目: 输入两棵二叉树A和B,判断B是不是A的子结构. 二叉树结构定义如下: struct TreeNode{ int val; TreeNode* left; TreeNode* right; }; ...
- 【剑指Offer】面试题18. 删除链表的节点
题目 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val = 5 ...
- 《剑指offer》面试题18. 删除链表的节点
问题描述 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val = ...
- 【剑指Offer学习】【全部面试题汇总】
剑指Offer学习 剑指Offer这本书已经学习完了.从中也学习到了不少的东西,如今做一个总的文件夹.供自已和大家一起參考.学如逆水行舟.不进则退.仅仅有不断地学习才干跟上时候.跟得上技术的潮流! 全 ...
随机推荐
- Sublime Text3快捷方式总结
Ctrl+P快速查找 Ctrl+D多行游标//同时选中多个地方进行编辑 Ctrl+F查找替换 Ctrl+H查找替换 Ctrl+G快速跳到某一行 Ctrl+shift+P命令模式 在命令模式下设置语法: ...
- API和DLL
API API(Application Programming Interface,应用编程接口)其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用 ...
- iOS 自定义各类bar的属性
在iOS应用开发中,经常需要为导航栏和标签栏设置相同的主题,一个一个去设置的话,就太麻烦了,可以通过对应用中所有的导航栏和标签栏同意设置背景.字体等属性. 如:创建一个继承自“UINavigation ...
- ##DAY5 UIControl及其子类
##DAY5 UIControl及其子类 #pragma mark ———————UIControl——————————— UIControl初识: 1)UIControl是有控制功能的视图(比如UI ...
- SQL基础常用语法
一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 DROP database dbname 3.说明:创建新表 create table ...
- JavaSE_ 网络编程 目录(26)
JavaSE学习总结第26天_网络编程26.01 网络编程概述26.02 网络模型概述和图解26.03 网络编程三要素概述26.04 网络编程三要素之IP概述126.05 InetAddress类的概 ...
- mysql 锁表查询及其处理
1.show OPEN TABLES where In_use > 0; 2.show processlist; 3.kill thread_id; 其中 thread_id为processli ...
- XHTML CSS 常见问题和解决方案
原文地址:XHTML CSS 常见问题和解决方案 作为前端开发人员,在日常的页面制作时,不可避免的会碰上这样那样的问题,我挑选了其中的一些进行总结归档,希望对大家会有所帮助: 1.如何定义高度很小的容 ...
- JS中的内存泄漏
明天下午面试微店的前端开发职位,有点紧张~~ 刚刚正好看到js中的内存泄露,所以来整理一番. 给DOM对象添加的属性是对一个js对象的引用. var MyObject = {}; document.g ...
- css 一些事
1.两个div左边的固定宽度右边的自动填充的css <div id="main" style="width:98%;"> <div id=&q ...