题目描述
- 给定一个二叉树,检查它是否是镜像对称的。
解法一:暴力解
- 审题之后思考,想了一下先中后序遍历的序列,发现中序遍历的序列是一个对称的序列,那么问题就可以转化为先遍历出序列在进行对称字符串的判断…自己能想到的最差的方法
- 时间复杂度为:遍历二叉树O(n),判断对称字符串O(n),故O(n)
- 空间复杂度为:需要数组空间存储序列O(n)
- 问题:
- 提交后发现代码健壮性存在问题
- 192 / 195 个通过测试用例
- 对于[1,2,2,2,null,2] 输入,确实存在着问题,由于存在着数据相同的情况,不能够进行准确判断…该法失效
public boolean isSymmetric(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
MidOrder(root,list);
int i=0,j=list.size()-1;
while(i<=j){
if(list.get(i)==list.get(j))
{
i++;
j--;
}else{
return false;
}
}
return true;
}
public void MidOrder(TreeNode root, ArrayList<Integer> list){
if(root==null)
return;
MidOrder(root.left,list);
list.add(root.val);
MidOrder(root.right,list);
}
解法二:递归
-
问题可以转化为:两个树在什么情况下互为镜像?如果同时满足下面的条件,两个树互为镜像:(该解参考LeetCode官方解答)
-
它们的两个根结点具有相同的值
-
每个树的右子树都与另一个树的左子树镜像对称
-
实现这样一个递归函数,通过同时移动两个指针的方法来遍历这棵树,root1指针和root2指针一开始都指向这棵树的根,随后root1右移时,root2左移,root1左移时,root2右移。每次检查当前 root1 和 root2 节点的值是否相等,如果相等再判断左右子树是否对称。
public boolean isSymmetric(TreeNode root) {
return Solution(root,root);
}
public boolean Solution(TreeNode root1,TreeNode root2){
if(root1==null&&root2==null){
return true;
}
if(root1==null||root2==null){
return false;
}
return root1.val==root2.val&&Solution(root1.left,root2.right)&&Solution(root1.right,root2.left);
}
时间复杂度:O(n)
空间复杂度:最大为O(n)
解法三:迭代
- 借助队列这种数据结构,思路跟递归法相同
public boolean isSymmetric(TreeNode root) {
return Solution(root,root);
}
public boolean Solution(TreeNode root1,TreeNode root2){
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root1);
queue.offer(root2);
while(!queue.isEmpty()){
root1 = queue.poll();
root2 = queue.poll();
if(root1==null&&root2==null){
continue;
}
if((root1==null||root2==null)||root1.val!=root2.val){
return false;
}
queue.offer(root1.left);
queue.offer(root2.right);
queue.offer(root1.right);
queue.offer(root2.left);
}
return true;
}
- 时间复杂度:O(n)
- 空间复杂度:最大为O(n)
- 总结:刷过这么多题后发现递归的效率比迭代的效率普遍要高,应该是在借助队列这种数据结构中消耗了多余时间,对于本题目来讲,递归超过百分百,但是迭代只有30左右。