26.
题目:
剑指 Offer 26. 树的子结构https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/
想法:首先在A中查找B的根节点,若找到则从此时起对比AB,否则返回false.
注意B==null时,不是任何树的子结构,可优先判断.
涉及两个递归:
递归一 findBsRoot
- 函数作用? 在A中查找B的根节点
输入:TreeNode A, TreeNode B
返回值:无 - 递归的终止条件?
A==null(查找完A) 或 flag==true(已经找到) - 本层递归与下一层的关系
若A.val==B.val,即已找到B的根节点,则调用第二个递归判断从此时开始A是否包含B
否则递归遍历A的左孩子/A的右孩子和B,以在A中寻找B.
递归二 compare
- 函数作用? 判断B是否为A的子结构
输入:TreeNode A, TreeNode B
返回值:是则返回true,否则返回false - 递归的终止条件?
B==null 说明B先遍历完,即A中包含B
A==null 说明A先遍历完,即A中不包含B - 本层递归与下一层的关系
本层需判断A.val==B.val是否成立,然后调用A.B的左孩子/A.B的右孩子
注意:每层的返回值应与上一层的作与运算,即全部相同才为子结构
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//法一:
class Solution {
boolean flag=false;
public boolean isSubStructure(TreeNode A, TreeNode B) {
//注意B==null时,不是任何树的子结构,可优先判断.
if(B==null) return false;
findBsRoot(A,B);
return flag;
}
//在A中查找B的根节点
void findBsRoot(TreeNode A, TreeNode B){
//flag为true时,说明已经找到子结构,结束遍历
if(A==null||flag)
return;
if(A.val==B.val)
//找到根节点,继续比较子节点,判断B是否为A的子结构
flag=compare(A,B);
findBsRoot(A.left,B);
findBsRoot(A.right,B);
}
//检查B是不是A的子结构
boolean compare(TreeNode A, TreeNode B){
//注意先判断B是否为空
if(B==null)
return true;
//后判断A是否为空
if(A==null)
return false;
//检查A.val是否等于B.val,并且递归检查A和B的左右子树
return A.val==B.val && compare(A.left,B.left) && compare(A.right,B.right);
}
}
//法二:不设flag也能写
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A==null||B==null) //空树不是任意一个树的子结构 空树也没有子结构
return false;
else //A和B为起点开始比较 或者A的左右孩子和B为起点开始比较
return judge(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B);
}
//依次对比每个节点,判断B是不是A的子结构
public boolean judge(TreeNode A, TreeNode B) {
//如果B先遍历完 说明B是A的子结构
if(B == null) return true;
//如果A先遍历完或者AB节点的值不一样了 说明B不是A的子结构
if(A == null || A.val != B.val) return false;
//依次对比左右孩子
return judge(A.left, B.left) && judge(A.right, B.right);
}
}
结果:
27.
题目:
剑指 Offer 27. 二叉树的镜像https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/
想法:依次交换所有节点的左右节点即可
递归 recursion
- 函数作用? 交换root节点的所有左右孩子
输入:TreeNode root
返回值:无 - 递归的终止条件?
root==null(遍历完root) - 本层递归与下一层的关系
先序遍历
交换此节点的左右孩子,再递归遍历其左孩子和右孩子
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//代码一:
class Solution {
public TreeNode mirrorTree(TreeNode root) {
//首先判断是否有根节点,可以省去后续步骤
recursion(root);
return root;
}
void recursion(TreeNode root){
if(root==null){
return;
}
TreeNode tmp=root.left;
root.left=root.right;
root.right=tmp;
recursion(root.left);
recursion(root.right);
}
}
参考他人发现可以直接在递归中返回节点
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//代码二:
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if (root == null) {
return null;
}
TreeNode leftRoot = mirrorTree(root.right);
TreeNode rightRoot = mirrorTree(root.left);
root.left = leftRoot;
root.right = rightRoot;
return root;
}
}
结果:
28.
题目:
剑指 Offer 28. 对称的二叉树https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/
想法:
递归二 compare
- 函数作用? 判断传入的两个树L.R是否镜像
输入:TreeNode L, TreeNode R
返回值:是则返回true,否则返回false - 递归的终止条件?
L==null 且 R==null -> 到底了都长得一样 -> 镜像
L==null.R!=null 或 L!=null.R==null -> 说明左右长得不一样 -> 非镜像
L.val!=R.val 节点值不相等 -> 长得不一样 -> 非镜像 - 本层递归与下一层的关系
判断完本层节点,需判断L树的左孩子与R树的右孩子是否一样
注意:空树必为镜像,可先进行判断
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
return root == null ? true : recur(root.left, root.right);
}
boolean recur(TreeNode L, TreeNode R) {
if(L == null && R == null)
return true;
if(L == null || R == null || L.val != R.val)
return false;
return recur(L.left, R.right) && recur(L.right, R.left);
}
}
结果: