PS:《剑指offer》是很多同学找工作都会参考的一本面试指南,同时也是一本算法指南(为什么它这么受欢迎,主要应该是其提供了一个循序渐进的优化解法,这点我觉得十分友好)。现在很多互联网的算法面试题基本上可以在这里找到影子,为了以后方便参考与回顾,现将书中例题用Java实现(第二版),欢迎各位同学一起交流进步。
GitHub: https://github.com/Uplpw/SwordOffer。
剑指offer完整题目链接: https://blog.youkuaiyun.com/qq_41866626/article/details/120415258
1 题目描述
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
leetcode链接: 树的子结构(以下代码已测试,提交通过)
2 测试用例
一般是考虑功能用例,特殊(边缘)用例或者是反例,无效测试用例这三种情况。甚至可以从测试用例寻找一些规律解决问题,同时也可以让我们的程序更加完整鲁棒。
(1)功能用例:A和B不为空,且包含是子结构以及不是子结构,情况分为结构以及节点值。
(2)边缘用例:单节点。
(3)无效用例:树为空。
3 思路
分析:
本题需要不但要判断树的结构一样,还要判断对应节点的值一样,可考虑递归实现。
具体过程:(假设树A和树B根节点不空)
当树A和树B根节点不空,比较当前节点值是否一样;
- 如果一样,进入递归比较判断方法,返回判断结果。
- 如果不一样,且上一步的结果为false,在当前方法递归循环,A的左子树和树B、以及A的右子树和树B。
递归比较判断方法过程(注意判断顺序,十分重要):
- 首先判断树B是否为空,为空直接返回true
- 判断树A是否为空,为空返回false;
- 判断树A与树B当前节点值是否相等,不相等返回false;相等,则在当前方法递归两个树对应的左、右子树。
4 代码
树的结构:
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
this.left = null;
this.right = null;
}
}
算法实现:
public class SubstructureInTree {
public static boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) {
return false;
}
boolean result = false;
if (A != null && B != null) {
if (A.val == B.val) {
result = tree1HasTree2FromRoot(A, B);
}
if (!result) {
result = isSubStructure(A.left, B);
}
if (!result) {
result = isSubStructure(A.right, B);
}
}
return result;
}
public static boolean tree1HasTree2FromRoot(TreeNode A, TreeNode B) {
if (B == null) {
return true;
}
if (A == null) {
return false;
}
if (A.val != B.val) {
return false;
}
return tree1HasTree2FromRoot(A.left, B.left) && tree1HasTree2FromRoot(A.right, B.right);
}
public static void main(String[] args) {
TreeNode root1 = new TreeNode(8);
root1.left = new TreeNode(8);
root1.right = new TreeNode(7);
root1.left.left = new TreeNode(9);
root1.left.right = new TreeNode(2);
root1.left.right.left = new TreeNode(4);
root1.left.right.right = new TreeNode(7);
TreeNode root2 = new TreeNode(8);
root2.left = new TreeNode(9);
root2.right = new TreeNode(2);
TreeNode root3 = new TreeNode(2);
root3.left = new TreeNode(4);
root3.right = new TreeNode(3);
System.out.println(isSubStructure(root1, root2));
System.out.println(isSubStructure(root1, root3));
}
}
参考
在解决本书例题时,参考了一些大佬的题解,比如leetcode上的官方、K神,以及其他的博客,在之后的每个例题详解后都会给出参考的思路或者代码链接,同学们都可以点进去看看!
本例题参考:
本文如有什么不足或不对的地方,欢迎大家批评指正,最后希望能和大家一起交流进步、拿到心仪的 offer !!!