一、今日刷题
1. 第七部分:二叉树 – 100. 相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
答案代码:
自己的思路,类似判断二叉树是否对称的代码,只不过将加入队列的节点由一棵二叉树的左右子树变成了两棵二叉树,但最后为了迁就满足所有情况,避免空指针异常,if语句写的太长了。
package BinaryTree;
import java.util.LinkedList;
import java.util.Queue;
/**
* @author: LYZ
* @date: 2022/2/26 10:11
* @description: 100.相同的树
*/
public class IsSameTree {
public static void main(String[] args) {
TreeNode p = new TreeNode(1, new TreeNode(2), new TreeNode(3));
TreeNode q = new TreeNode(1, new TreeNode(2), new TreeNode(3));
TreeNode f = new TreeNode(1, new TreeNode(3), new TreeNode(2));
IsSameTree isSameTree = new IsSameTree();
boolean ans = isSameTree.isSameTree(p, f);
System.out.println(ans);
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
} //因为当程序运行到这一段代码时,上一段已经确定 p、q 节点不同时为空了,所有只有两节点有一个为空,就可返回false
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while (!queue.isEmpty()) {
TreeNode nodeP = queue.poll();
TreeNode nodeQ = queue.poll();
//看idea原代码,在这里先写了一段处理 p、q 为空/不为空等情况的if语句
//但如果先判断现有节点,在向队列插入新节点时会遇到空指针异常
//所以要在插入新节点时就处理一些空值的情况,使得将节点插入队列具有了更纯粹的目的 —— 比较p、q节点的值
if (nodeP != null && nodeQ != null && nodeP.val != nodeQ.val) {
return false;
} else if (nodeP.left == null && nodeQ.left != null) {
return false;
} else if (nodeP.left != null && nodeQ.left == null) {
return false;
} else if (nodeP.right == null && nodeQ.right != null) {
return false;
} else if (nodeP.right != null && nodeQ.right == null) {
return false;
} else {
if (nodeP.left != null) {
queue.offer(nodeP.left);
}
if (nodeQ.left != null) {
queue.offer(nodeQ.left);
}
if (nodeP.right != null) {
queue.offer(nodeP.right);
}
if (nodeQ.right != null) {
queue.offer(nodeQ.right);
}
}
}
return true;
}
}
2. 第七部分:二叉树 – 572. 另一棵树的子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
答案代码:
遍历以 root 为根的这棵二叉树的所有节点,用 100. 相同的树 中的 isSame 函数判断以该节点为根的子树是否和以 subRoot 为根的那棵树相同。
package BinaryTree;
import java.util.LinkedList;
import java.util.Queue;
/**
* @author: LYZ
* @date: 2022/2/26 11:15
* @description: 572. 另一棵树的子树
*/
public class IsSubtree { //力扣的这个类名不对,没遵守大驼峰
public static void main(String[] args) {
TreeNode p = new TreeNode(1, new TreeNode(1, new TreeNode(2), new TreeNode(3)), new TreeNode(6));
TreeNode q = new TreeNode(1, new TreeNode(2), new TreeNode(3));
IsSubtree isSubtree = new IsSubtree();
boolean ans = isSubtree.isSubtree(p, q);
System.out.println(ans);
}
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (root == null) {
return subRoot == null; //注意这里,之前没这么写过
}
if (isSameTree(root, subRoot)) {
return true;
}
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
} //因为当程序运行到这一段代码时,上一段已经确定 p、q 节点不同时为空了,所有只有两节点有一个为空,就可返回false
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while (!queue.isEmpty()) {
TreeNode nodeP = queue.poll();
TreeNode nodeQ = queue.poll();
//看idea原代码,在这里先写了一段处理 p、q 为空/不为空等情况的if语句
//但如果先判断现有节点,在向队列插入新节点时会遇到空指针异常
//所以要在插入新节点时就处理一些空值的情况,使得将节点插入队列具有了更纯粹的目的 —— 比较p、q节点的值
if (nodeP != null && nodeQ != null && nodeP.val != nodeQ.val) {
return false;
} else if (nodeP.left == null && nodeQ.left != null) {
return false;
} else if (nodeP.left != null && nodeQ.left == null) {
return false;
} else if (nodeP.right == null && nodeQ.right != null) {
return false;
} else if (nodeP.right != null && nodeQ.right == null) {
return false;
} else {
if (nodeP.left != null) {
queue.offer(nodeP.left);
}
if (nodeQ.left != null) {
queue.offer(nodeQ.left);
}
if (nodeP.right != null) {
queue.offer(nodeP.right);
}
if (nodeQ.right != null) {
queue.offer(nodeQ.right);
}
}
}
return true;
}
}