二叉树day4
继续昨天,迭代法实现对称二叉树
101. 对称二叉树
//迭代 队列,栈同理,因为每次都是对一层进行操作
class Solution {
public boolean isSymmetric(TreeNode root) {
Deque<TreeNode> queue = new LinkedList<>();
if (root == null) return true;
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode left = queue.poll(), right = queue.poll();
//当层该对结点为null,对称,转而继续判断下一对结点(如果有)
if (left == null && right == null) continue;
//不对称的三种情况
if (left == null || right == null || (left.val != right.val)) return false;
//该层该对结点对称且子结点不为空,子结点入队继续进行判断
//外层
queue.offer(left.left);
queue.offer(right.right);
//内层
queue.offer(left.right);
queue.offer(right.left);
}
return true;
}
}
100. 相同的树
//迭代 层序
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while (!queue.isEmpty()) {
TreeNode first = queue.poll();
TreeNode second = queue.poll();
if (first == null && second == null) continue;
if (first == null || second == null || first.val != second.val) return false;
queue.offer(first.left);
queue.offer(second.left);
queue.offer(first.right);
queue.offer(second.right);
}
return true;
}
}
//递归 前序 中左右
// class Solution {
// public boolean isSameTree(TreeNode p, TreeNode q) {
// return dfs(p, q);
// }
// private boolean dfs(TreeNode p, TreeNode q) {
// if (p == null && q == null) return true;
// else if(p != null && q == null) return false;
// else if(p == null && q != null) return false;
// else if(p.val != q.val) return false;
// else return (dfs(p.left, q.left) && dfs(p.right, q.right));
// }
// }
解决了相同的树这一题,572题便很轻松可以解决。
572. 另一棵树的子树
递归
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
return preOrder(root, subRoot);
}
//前序遍历主树找到与从树根节点值相同的结点
private boolean preOrder(TreeNode root, TreeNode subRoot) {
if (root == null && subRoot == null) return true;
//主树与丛树有一个为空,则返回false,两者同时为空的情况前面已经处理所以这里不会出现
else if (root == null || subRoot == null) return false;
// //值不相等,前序遍历主树
// else if (root.val != subRoot.val) return preOrder(root.left, subRoot) || preOrder(root.right, subRoot);
// //找到与从树根节点值相等的节点,开始判断子树是否存在的逻辑
// else if(dfs(root.left, subRoot.left) && dfs(root.right, subRoot.right)) return true;
// //继续找具有相同值的结点
// else return preOrder(root.left, subRoot) || preOrder(root.right, subRoot);
//改进
/* 一个树是另一个树的子树 则
* 要么这两个树相等
* 要么这个树是左树的子树
* 要么这个树hi右树的子树
**/
else return dfs(root, subRoot) || preOrder(root.left, subRoot) || preOrder(root.right, subRoot);
}
//相同的树
private boolean dfs(TreeNode first, TreeNode second) {
if (first == null && second == null ) return true;
else if (first == null || second == null || first.val != second.val) return false;
else return dfs(first.left, second.left) && dfs(first.right, second.right);
}
}
迭代
//迭代 遍历主树和判断相同树都用层序遍历实现
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
//空树是任何树的子树
if (subRoot == null) return true;
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(root);
//遍历主树
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
Deque<TreeNode> queueSame = new LinkedList<>();
queueSame.offer(cur);
queueSame.offer(subRoot);
//判断是否为相同树
while (!queueSame.isEmpty()) {
TreeNode first = queueSame.poll(), second = queueSame.poll();
if (first == null && second == null) continue;
else if (first == null || second == null || first.val != second.val){
//装入一个值退出循环,作为相同树判断结果为false的标志
queueSame.offer(first);
break;
}
queueSame.offer(first.left);
queueSame.offer(second.left);
queueSame.offer(first.right);
queueSame.offer(second.right);
}
//队列为空则该次判断相同树结果为true
if (queueSame.isEmpty()) return true;
if (cur != null) {
queue.offer(cur.left);
queue.offer(cur.right);
}
}
//层序遍历完所有结点未找到相同树,即无子树
return false;
}
}
看了一下官解,明天学习一下使用KMP和树哈希来解决此题。简单题不简单。