🚩传送门:牛客题目

题目

给定一棵二叉树,判断其是否是自身的镜像(即:是否对称

例如:下面这棵二叉树是对称的
[NC]16. 对称的二叉树 - 图1

例如:下面这棵二叉树不对称
image.png

解题思路:递归

据题意,对称二叉树定义为:「若一棵二叉树与其镜像二叉树是相同的,则其是对称的二叉树」。

  1. 从根结点开始,判断其左右子树是否对称,即判断「结点1所在子树」和「结点2所在子树」是否对称;
  2. 为比较这两个子树的对称情况,需要分别比较各自的左右孩子的对称情况,即:比较「结点3所在子树」和「结点4所在子树」是否对称,同时也需要比较「结点5所在子树」和「结点6所在子树」是否对称;
  3. 依次类推,直至遍历到叶子结点。

image.png
image.png

复杂度分析

时间复杂度: [NC]16. 对称的二叉树 - 图5 ,该方法需要遍历树的所有结点 。

空间复杂度:[NC]16. 对称的二叉树 - 图6 ,该方法在递归时需要使用栈空间 。

我的代码

  1. class Solution {
  2. static class TreeNode {
  3. int val;
  4. TreeNode left;
  5. TreeNode right;
  6. }
  7. public boolean isSymmetrical(TreeNode pRoot) {
  8. if (pRoot==null)
  9. return true;
  10. return helper(pRoot.left, pRoot.right);
  11. }
  12. public boolean helper(TreeNode left, TreeNode right) {
  13. if (left==null&&right==null) // 两个结点同时为空,必对称
  14. return true;
  15. if (left==null||right==null) // 两个结点有一个为空
  16. return false;
  17. if (left.val != right.val) // 两个结点取值不同,必不对称
  18. return false;
  19. // 递归地遍历左子树的左孩子与右子树的右孩子,以及右子树的左孩子与左子树的右孩子
  20. return helper(left.left, right.right) && helper(left.right, right.left);
  21. }
  22. }

解题思路:非递归

利用队列进行层次遍历,将每一层用临时的列表保存下来,然后对当前一层进行判断是否对称。

由于结点数据最大 1000,所以空结点用 1001 来表示 。

复杂度分析

时间复杂度: [NC]16. 对称的二叉树 - 图7 ,该方法需要遍历树的所有结点 。

空间复杂度:[NC]16. 对称的二叉树 - 图8 ,该方法在递归时需要使用队列空间 。

我的代码

  1. public class Solution {
  2. public class TreeNode {
  3. int val = 0;
  4. TreeNode left = null;
  5. TreeNode right = null;
  6. public TreeNode(int val) {
  7. this.val = val;
  8. }
  9. }
  10. //判断当前层是否对称
  11. boolean isCurLyerSymmetrical(ArrayList<Integer>list){
  12. int i=0;
  13. int j=list.size()-1;
  14. while(i<j){
  15. if(list.get(i).equals(list.get(j))){
  16. i++;j--;
  17. }
  18. else return false;
  19. }
  20. return true;
  21. }
  22. //层次遍历存储拿到每一层
  23. boolean isSymmetrical(TreeNode pRoot) {
  24. LinkedList<TreeNode>q=new LinkedList<>();
  25. ArrayList<Integer>list=new ArrayList<>();
  26. if(pRoot==null)return true;
  27. q.add(pRoot);
  28. while(!q.isEmpty()){
  29. int n=q.size();
  30. list.clear();
  31. TreeNode node=null;
  32. //拿到每一层的结点
  33. for(int i=0;i<n;i++){
  34. node=q.poll();
  35. if(node.left!=null){
  36. q.add(node.left);
  37. list.add(node.left.val);
  38. }else{
  39. list.add(1001); //表示当前结点的左孩子是null
  40. }
  41. if(node.right!=null){
  42. q.add(node.right);
  43. list.add(node.right.val);
  44. }else{
  45. list.add(1001); //表示当前结点的右孩子是null
  46. }
  47. }
  48. if(!isLyerSymmetrical(list))
  49. return false;
  50. }
  51. return true;
  52. }
  53. }