参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:树的子结构
输入两棵二叉树A和B,判断B是不是A的子结构。
例如:
A:
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
B:
// 6
// /\
// 4 8
B是A的子树
主要思路:
第一步:在树A中找到和树B的根节点值一样的结点R,该过程可通过递归遍历树A的节点实现(先找父节点,再找左右子节点)。
第二步:判断在树A中以R为根节点的子树结构是否和树B的结构一样,可通过递归来判断它们各自的父节点和左右子节点是否一样。
关键点:递归,二叉树遍历
时间复杂度:O(nB)~O(nAnB)
public class SubTree {
public static void main(String[] args) {
TreeNode root1 = TreeNode.generateBinaryTree();
TreeNode root2 = TreeNode.generateSubTree();
System.out.println(hasSubtree(root1, root2));
}
private static boolean hasSubtree(TreeNode root1, TreeNode root2) {
boolean result = false;
if (root1 == null || root2 == null) {
return false;
}
if (root1.val == root2.val) {
result = isTree1HaveTree2(root1, root2);
}
if (!result) {
//判断是否是root1左树的子树
result = hasSubtree(root1.left, root2);
}
if (!result) {
//判断是否是root1右树的子树
result = hasSubtree(root1.right, root2);
}
return result;
}
private static boolean isTree1HaveTree2(TreeNode tree1, TreeNode tree2) {
//Tree2遍历完,说明是子树,返回true
if (tree2 == null) {
return true;
}
//如果Tree2还没有遍历完,Tree1却遍历完了,返回false
if (tree1 == null) {
return false;
}
//节点值不相等,返回false
if (tree1.val != tree2.val) {
return false;
}
//判断左右子树是否满足条件
return isTree1HaveTree2(tree1.left, tree2.left) && isTree1HaveTree2(tree1.right, tree2.right);
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
/**
* 生成二叉搜索树
*
* @return
*/
public static TreeNode generateBinaryTree() {
TreeNode root = new TreeNode(10);
TreeNode node6 = new TreeNode(6);
TreeNode node14 = new TreeNode(14);
TreeNode node4 = new TreeNode(4);
TreeNode node8 = new TreeNode(8);
TreeNode node12 = new TreeNode(12);
TreeNode node16 = new TreeNode(16);
connectNode(root, node6, node14);
connectNode(node6, node4, node8);
connectNode(node14, node12, node16);
return root;
}
// 6
// /\
// 4 8
/**
* 生成子树
*
* @return
*/
public static TreeNode generateSubTree() {
TreeNode node6 = new TreeNode(6);
TreeNode node4 = new TreeNode(4);
TreeNode node8 = new TreeNode(8);
connectNode(node6, node4, node8);
return node6;
}
private static void connectNode(TreeNode root, TreeNode left, TreeNode right) {
root.left = left;
root.right = right;
}
}