第一题
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
解题思路:
先序遍历A树,判断以nA为根节点的子树是否包含树B
代码实现:
/**
* 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) {
return (A!=null && B!=null) && (contrast(A,B) ||isSubStructure(A.left,B) ||isSubStructure(A.right,B));
}
public boolean contrast(TreeNode A,TreeNode B){
if(B==null) return true;
if(A==null || A.val!=B.val) return false;
return contrast(A.left,B.left)&&contrast(A.right,B.right);
}
}
总结:
这一句实现了对isSubStructure的反复调用。
return (A!=null && B!=null) && (contrast(A,B) ||isSubStructure(A.left,B) ||isSubStructure(A.right,B));
比如对于上述两个树
第一次调用
isSubStructure(A,B)
contrast(A,B),return false
isSubStructure(A.left,B) //A.left.val==2,B.val==4
contrast(A.left,B) return false
isSubStructure(A.left,B) //A.left.val==4,B.val==4
contrast(A,B) return true;
return true;
return true;
第二题
解题思路:
考虑dfs,交换每个节点的子节点即可。又,每个节点都需要交换操作,故考虑递归实现
代码实现:
/**
* 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 leftV=root.left;
root.left=mirrorTree(root.right);
root.right=mirrorTree(leftV);
return root;
}
}
第三题
解题思路:
做递归思考三步:
- 递归的函数要干什么?
- 函数的作用是判断传入的两个树是否镜像。
- 输入:TreeNode left, TreeNode right
- 输出:是:true,不是:false
- 递归停止的条件是什么?
- 左节点和右节点都为空 -> 倒底了都长得一样 ->true
- 左节点为空的时候右节点不为空,或反之 -> 长得不一样-> false
- 左右节点值不相等 -> 长得不一样 -> false
- 从某层到下一层的关系是什么?
- 要想两棵树镜像,那么一棵树左边的左边要和二棵树右边的右边镜像,一棵树左边的右边要和二棵树右边的左边镜像
- 调用递归函数传入左左和右右
- 调用递归函数传入左右和右左
- 只有左左和右右镜像且左右和右左镜像的时候,我们才能说这两棵树是镜像的
- 调用递归函数,我们想知道它的左右孩子是否镜像,传入的值是root的左孩子和右孩子。这之前记得判个root==null。
代码实现:
/**
* 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) {
if(root==null) return true;
return contrast(root.left,root.right);
}
private boolean contrast(TreeNode node1,TreeNode node2){
if(node1==null&&node2==null) return true;
if((node1==null&&node2!=null)||(node1!=null&&node2==null)||(node1.val != node2.val)) return false;
return contrast(node1.left,node2.right)&&contrast(node1.right,node2.left);
}
}
K神精简版代码:
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);
}
}
作者:Krahets
链接:https://leetcode.cn/problems/dui-cheng-de-er-cha-shu-lcof/solutions/131626/mian-shi-ti-28-dui-cheng-de-er-cha-shu-di-gui-qing/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
可以学习的点:
因为第一条已经判断了L和R同时为空的情况,所以后面不需要冗杂的写L为空R不为空、L不为空R为空、比较L和R的val值,只需要简单地判断L为空或R为空或L/R的val值是否相等