剑指 Offer 26. 树的子结构
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
示例 1:
输入:A = [1,2,3], B = [3,1]
输出:false
示例 2:
输入:A = [3,4,5,1,2], B = [4,1]
输出:true
限制:
0 <= 节点个数 <= 10000
思路
二叉树一般使用:递归、遍历来解决
该题分为两步:
第一步,在树A中找到和树B的根节点的值一样的节点R;
第二步,判断树A中以R为根节点的子树是不是包含和树B一样的结构。
两步都可以使用递归来实现
递归需要注意临界条件,即结束条件
第二步中,
如果节点 R 的值和树 B的根节点不相同,则以R为根节点的子树和树 B肯定不具有相同的节点;
如果它们的值相同,则递归地判断它们各自的左右节点的值是不是相同。
递归的终止条件是我们到达了树 A或者树 B的叶节点
得出Java程序代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
//首先判断边界条件
if (A == null || B == null) return false;
//遍历A,找出树A中,节点的值与B的根节点的值相等的节点
//如果值相等,并且还有相同的结构,则返回true
if (A.val == B.val && isMatch(A, B)) {
//假设找到树A中,R节点的值与B的根节点的值相等
//判断以R为根节点的树,与以B为根节点的树,结构是否相同
return true;
}else{
return isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
}
//判断,以R为根节点,以B为根节点的两棵树,是否有相同结构
public boolean isMatch(TreeNode R, TreeNode B) {
if (B == null) return true;//如果B比较的没有了,那么说明B比较完了,满足要求
if (R == null) return false;//如果R比较的没有了,B还有,不满足条件
if (R.val != B.val) return false;
return isMatch(R.left, B.left) && isMatch(R.right, B.right);
}
}
注意
上述代码中,
if (B == null) return true;
if (R == null) return false;
不可以写反:
if (R == null) return false;
if (B == null) return true;
如果写反了,先判断R是否为null,如果R == null
且B == null
那么,这时会返回false,这,是不对的。