101. 对称二叉树
https://leetcode-cn.com/problems/symmetric-tree/
递归法:
其实这题的解法已经是很成熟的了,大概就是你需要比较当前根节点的两个叶子节点是否相等,然后再把相对应的节点一一继续比较,这就是判断二叉树是否对称的惯用解法。其实这个题目官方的解答不可谓不好,我们可以直接来看代码。
class Solution {
public boolean isSymmetric(TreeNode root) {
return isMirror(root, root);
}
public boolean isMirror(TreeNode leftNode, TreeNode rightNode) {
if (leftNode == null && rightNode == null) {
return true;
} else if (leftNode == null || rightNode == null) {
return false;
} else if (leftNode.val != rightNode.val) {
return false;
}
boolean node1 = isMirror(leftNode.left, rightNode.right);
boolean node2 = isMirror(leftNode.right, rightNode.left);
return node1 && node2;
}
}
但是有一点就是,这种思路可能不会第一时间想到,那么我在这里提供另一种解答方法,虽然都是递归,但是我相信,这种思路应该会更加好理解的。
首先我们先明白『先序遍历』的顺序是:根 -> 左 -> 右;
那么我们能否来一个『反先序遍历』呢?顺序就是:根 -> 右 -> 左
看到这里,你大概就能猜到了,接下来我们只要保证两个两个遍历的所经过的节点的值都是相同的,那么就是对称二叉树了。那么有着这种思路,我们来看一下代码:
class Solution {
List<TreeNode> proList = new LinkedList<>();
List<TreeNode> unProList = new LinkedList<>();
public boolean isSymmetric(TreeNode root) {
proTraversing(root);
unProTraversing(root);
int len = proList.size();
int unLen = unProList.size();
if (len != unLen) {
return false;
} else {
for (int i = 0; i < len; ++i) {
if (proList.get(i) == null && unProList.get(i) == null) {
continue;
} else if (proList.get(i) == null || unProList.get(i) == null) {
return false;
} else if (proList.get(i).val != unProList.get(i).val) {
return false;
}
}
}
return true;
}
private void proTraversing(TreeNode node) {
if (node == null) {
proList.add(node);
return;
}
proList.add(node);
proTraversing(node.left);
proTraversing(node.right);
}
private void unProTraversing(TreeNode node) {
if (node == null) {
unProList.add(node);
return;
}
unProList.add(node);
unProTraversing(node.right);
unProTraversing(node.left);
}
}
以上就是这个思路,其实速度不快,就是好理解。
迭代法:
其实这题,我只想到用递归,但是其实按理来说,如果你精通二叉树的层遍历,那么迭代法会更加简单,下面我直接引用官方的解答:
除了递归的方法外,我们也可以利用队列进行迭代。队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像。最初,队列中包含的是 root 以及 root。该算法的工作原理类似于 BFS,但存在一些关键差异。每次提取两个结点并比较它们的值。然后,将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。
其实我觉得这解答写的,额。不咋好,有空我会根据我的思路重新做一做,我们先来看看官方的解答的代码:
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
q.add(root);
while (!q.isEmpty()) {
TreeNode t1 = q.poll();
TreeNode t2 = q.poll();
if (t1 == null && t2 == null) continue;
if (t1 == null || t2 == null) return false;
if (t1.val != t2.val) return false;
q.add(t1.left);
q.add(t2.right);
q.add(t1.right);
q.add(t2.left);
}
return true;
}