LeetCode 100. 相同的树
按顺序遍历所有节点(包括空节点)(自己的错误思路)
以相同的次序依次遍历两颗树,记录结点值,再比较。就用层序遍历,但是这样必须得遍历完一棵树。如果遇到null就添加-1。
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
//首先结点的值要相同,可以层序遍历一遍,每个位置结点的值是否相同,但是要遍历两颗树?开辟两个空间?
//还是用递归比较好,但是也要遍历两颗树?
//同时遍历两颗树绝对不行,同时拿两棵树对比也肯定不行
//以相同的次序依次遍历两颗树,记录结点值,再比较。就用层序遍历,但是这样必须得遍历完一棵树
List<Integer> resp = new ArrayList<>();
List<Integer> resq = new ArrayList<>();
resp = search(p);
resq = search(q);
System.out.println(resp);
System.out.println(resq);
if(resp.size() == resq.size()){
for(int a:resq){
if(!resp.contains(a)) return false;
}
}
return true;
}
//层序遍历
public List<Integer> search(TreeNode root){
List<Integer> res = new ArrayList<>();
if(root == null){
res.add(-1);
return res;
}
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
int len = que.size();
while(len>0){
TreeNode node = que.poll();
res.add(node.val);
if(node.left==null) res.add(-1);
else que.offer(node.left);
if(node.right==null) res.add(-1);
else que.offer(node.right);
len--;
}
}
return res;
}
}
本身分别得到的结果应该是[1,2,-1,-1,-1]和[1,-1,2,-1,-1]的,但是由于程序遍历这里不是用递归,没有回溯。当遍历到空节点时就加入-1,不能做到先遍历完左子树的全部结点,再去遍历右子树的内容。所以它不能判别对称的情况。
if(node.left==null) res.add(-1);
else que.offer(node.left);
if(node.right==null) res.add(-1);
else que.offer(node.right);
所以我的想法是应该采用前序遍历+后序遍历确定一棵树。但是这种思路也比较麻烦。下面看正确思路。
正确思路(递归法和迭代法)
递归
分别比较两棵树的左子树、右子树。与对称二叉树相似的解法(做了一点点小改变)。
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
return compare(p,q);
}
public boolean compare(TreeNode left,TreeNode right){
// 首先排除空节点的情况
if (left == null && right != null) return false;
else if (left != null && right == null) return false;
else if (left == null && right == null) return true;
// 排除了空节点,再排除数值不相同的情况
else if (left.val != right.val) return false;
boolean outside = compare(left.left, right.left); // 左子树:左、 右子树:左 (相对于求对称二叉树,只需改一下这里的顺序)
boolean inside = compare(left.right, right.right); // 左子树:右、 右子树:右
boolean isSame = outside && inside; // 左子树:中、 右子树:中 (逻辑处理)
return isSame;
}
}
迭代
采用双端队列,注意遍历孩子节点也需要同样的判断。
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q==null) return true;//空的树也是对称
if(p==null || q==null) return false;
Deque<TreeNode> deque = new LinkedList<TreeNode>();//双端队列
deque.offerFirst(p);//注意用法First 和 Last 分别指两个队列
deque.offerLast(q);
while(!deque.isEmpty()){
TreeNode curp = deque.pollFirst();
TreeNode curq = deque.pollLast();
if(curp == null && curq == null){
continue;
}
else if(curp == null|| curq == null||curp.val!=curq.val){
//三种情况,其中值不同指的是整个左孩子的值
return false;
}
//将孩子插入队列,以便再次进入while循环
deque.offerFirst(curp.left);//左右,下一次循环时先出left
deque.offerFirst(curp.right);
deque.offerLast(curq.left);
deque.offerLast(curq.right);
}
return true;
}
}