题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
建议打开这个以及101的那篇对着看。
import java.util.*;
public class Solution {
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
public void unPreOrder(TreeNode root){
if(root == null)
list1.add(null);
else{
list1.add(root.val);
unPreOrder(root.right);
unPreOrder(root.left);
}
}
public void preOrder(TreeNode root){
if(root == null)
list2.add(null);
else{
list2.add(root.val);
preOrder(root.left);
preOrder(root.right);
}
}
boolean isSymmetrical(TreeNode pRoot)
{
if(pRoot == null)
return true;
unPreOrder(pRoot);
preOrder(pRoot);
for(int i=0;iif(list1.get(i) != list2.get(i))
return false;
}
return true;
}
}
本来想使用一个镜像函数来做,发现使用后,原来的树节点就变成它的镜像了,无法进行比较。
做一个先序遍历的对称遍历,然后比较他们的元素。为了避免树中所有节点都相同,存储的时候还带了null节点。
可以通过比较二叉树的前序遍历和二叉树对称前序遍历来判断二叉树是不是对称的。
还是那一套,一种是先遍历,保存在数组中,然后进行处理(判断两数组是否相同);
另一种是在遍历的同时进行判断处理。
意识到镜像是当前二叉树将所有的左右节点进行交换而生成的,所以:
public class Solution {
boolean isSymmetrical(TreeNode root1,TreeNode root2){
if(root1 == null && root2 == null)
return true;
if(root1 == null || root2 == null)
return false;
//下面这两段很重要
if(root1.val != root2.val)
return false;
return isSymmetrical(root1.left,root2.right)
&& isSymmetrical(root1.right,root2.left);
}
boolean isSymmetrical(TreeNode pRoot)
{
return isSymmetrical(pRoot,pRoot);
}
}
if(root1.val != root2.val)
return false;
return isSymmetrical(root1.left,root2.right)
&& isSymmetrical(root1.right,root2.left);
也可以写成
return root1.val == root2.val && isSymmetrical(root1.left,root2.right)
&& isSymmetrical(root1.right,root2.left);
LeetCode的代码:
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
class Solution {
public boolean leftEqualsRight(TreeNode root1,TreeNode root2) {
if(root1 == null && root2 == null)
return true;
if(root1 == null || root2 == null)
return false;
if(root1.val != root2.val)
return false;
return leftEqualsRight(root1.left,root2.right) && leftEqualsRight(root1.right,root2.left);
}
public boolean isSymmetric(TreeNode root) {
if(root == null)
return true;
return leftEqualsRight(root,root);
}
}
注意: //if(root1.val == root2.val) // return true;显然这个不是递归的终结条件!
迭代:
class Solution {
public boolean leftEqualsRight(TreeNode root1,TreeNode root2) {
Stack stack1 = new Stack();
Stack stack2 = new Stack();
TreeNode p = root1,q = root2;
while((!stack1.isEmpty() && !stack2.isEmpty()) || (p != null && q != null)){
if(p != null && q != null){
stack1.push(p);
p = p.left;
stack2.push(q);
q = q.right;
}else if((p == null&& q != null) || (p != null&& q == null)){
return false;
}else{
p = stack1.pop();
q = stack2.pop();
if(p.val != q.val)
return false;
p = p.right;
q = q.left;
}
}
return true;
}
public boolean isSymmetric(TreeNode root) {
if(root == null)
return true;
return leftEqualsRight(root,root);
}
}
先序遍历:这里请重点关注
class Solution {
public boolean leftEqualsRight(TreeNode root1,TreeNode root2) {
Stack stack1 = new Stack();
Stack stack2 = new Stack();
stack1.push(root1);
stack2.push(root2);
while(!stack1.isEmpty() && !stack2.isEmpty()){
TreeNode p = stack1.pop();
TreeNode q = stack2.pop();
if(p.val != q.val
|| (p.right == null && q.left != null)
|| (p.right != null && q.left == null)
|| (p.left != null && q.right == null)
|| (p.left == null && q.right != null))
return false;
if(p.right != null && q.left != null){
stack1.push(p.right);
stack2.push(q.left);
}
if(p.left != null && q.right != null){
stack1.push(p.left);
stack2.push(q.right);
}
}
return true;
}
public boolean isSymmetric(TreeNode root) {
if(root == null)
return true;
return leftEqualsRight(root,root);
}
}
前序遍历入栈的时候必须得对两个节点进行null的判断!否则,第二个例子怎么样都是一样的结果!
都需要对两个节点进行null的判断呀!