题目:相同的树
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
四步走模板
四步走模板主要用于判断两个节点是否是相同的,下面的逻辑关系是层层递进的
- 如果两个节点都是空的,返回true
- 不满足之前的所有条件,并且两个节点中一个为空,返回false
- 不满足之前的所有条件,并且两个节点的值不等,返回false
- 不满足之前的所有条件,说明两个节点的值相等,继续递归子树
下面算是四步法的经典代码了
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
// 四步走
// 如果都为空,说明满足条件
if(p==null && q==null) return true;
// 如果只有一方为空,不满足条件
if(p==null || q==null) return false;
// s和 t此时都不为空,如果不相等,则不满足条件
if(p.val != q.val) return false;
// 继续递归两个的左子树是否相同和右子树是否相同
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
题目:对称的二叉树
原题链接
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
对于这种二叉树的对称问题,也是套四步法的模板,不过最后递归的时候递归的是左子树的左子树和右子树的右子树比较
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return helper(root.left, root.right);
}
// 帮助方法四步走
boolean helper(TreeNode left, TreeNode right){
if(left == null && right == null){
return true;
}
if(left == null || right == null){
return false;
}
if(left.val != right.val){
return false;
}
// 这一步的条件有所调整
return helper(left.left, right.right) && helper(left.right, right.left);
// 相同的树,是这么写的
// return isSameTree(left.left, right.left) && isSameTree(left.right, right.right);
}
}
一开始这题竟然提交没通过,检查了才知道原来自己的返回值不匹配。
if(root == null) return true
如果根节点为空(即一颗空的二叉树),它也是对称的,而且需要返回true
。不能直接返回 null
题目:另一个树的子树
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
示例 1:
给定的树 s:
3
/ \
4 5
/ \
1 2
给定的树 t:
4
/ \
1 2
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
四步法 + 双递归解法
树 s中的每一个节点都有可能成为子树的起点,所以需要递归树 s的每个节点
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
// 这里使用到了双递归
if(s==null)
return false;
// 只要当前节点或者左右子树中有一个 满足是另一个子树的起点就好了,所以三个 "||"
return helper(s, t)||isSubtree(s.left, t)||isSubtree(s.right, t);
}
public boolean helper(TreeNode s, TreeNode t){
// 四步走
if(s == null && t == null){
return true;
}
if(s == null || t == null){
return false;
}
if(s.val != t.val){
return false;
}
return helper(s.left, t.left)&&helper(s.right, t.right);
}
}
题目:树的子结构
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
题目分析
这里与上一个题(另一个树的子树)比较类似,也是可以用 四步法+双递归。
不过需要注意概念上的差别,子树是从某个节点开始,之后的所有节点都和父节点相同。 而子结构则是,它有的结构,父树中都有,而父树中有的结构它不一定有,上图:
上面右边那棵树是左边树的子结构(虽然没有3和11),结构却基本相同。但是右边树不是左边树的子树(子树的要求挺高)
所以 四步法的需要做一点点调整,即 B的子树中如果有空节点,而A中的该位置不为空,并不影响B是A的子结构。
解题代码
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
return (A==null || B == null) ? false : helper(A,B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
boolean helper(TreeNode left, TreeNode right){
// 只用子结构没有这个节点,那么树有没有不重要,返回true
if(right == null) return true;
// if(left==null && right==null) return true; //两个树都是空
// 如果子结构有的,树没有,则false
if(left == null) return false;
// if(left==null || right==null) return false; //有一个树不为空
if(left.val != right.val) return false;
return helper(left.left, right.left) && helper(left.right, right.right);
}
}
后记
看到最后了的话,可以访问我的CSDN博客主页。
搜索关键字“模板”,看到更多刷题模板!!