【LeetCode - Java】101. 对称二叉树 (简单)

1. 题目描述

在这里插入图片描述

2. 解题思路

这道题目一开始我其实是并不想从纯结构方面去判断一个二叉树是否对称的,总感觉有没有一点稍微“高级”的方法,于是想起了昨天做的中序遍历,会不会利用中序遍历结果可以判断呢?那就一起来看看
在这里插入图片描述
在这里插入图片描述
看起来是似乎可以通过判断中序遍历输出是否回文数来间接判断这棵树是否对称,当我信心满满地提交代码后发现,对于这个树,我是错了的:
在这里插入图片描述
然后我又思考了片刻,发现:
在这里插入图片描述
似乎我又对了?代码提交!fine还是有问题,什么问题呢?请看:
在这里插入图片描述
然后,我又依据这玩意构建了个满二叉树
在这里插入图片描述
当我整完这一通操作之后,感觉这个做法似乎意义不大了,还得构建满二叉树,浪费时间浪费储存。然后我转而到了纯结构的路上了

纯结构的递归没什么好介绍的,无非就是分开左子树节点的左孩子与右子树节点的右孩子比较,左子树节点的右孩子与右子树节点的左孩子比较,仅此而已。

纯结构的迭代就有点意思了,但在递归中使用的是先进后出,而在迭代中,我第一个想法是使用队列先进先出,借鉴广度优先搜索的概念,对二叉树进行一层层处理,每处理一层则把该层的孩子(左子树的左孩子和右子树的右孩子,左子树的右孩子和右子树的左孩子)塞进队列中,若最后队列都为空则代表是对称结构了。

3. 代码实现

3.1 利用中序遍历(卒 | 小部分情况无法解决 除非构建满二叉树)

public boolean isSymmetric(TreeNode root) {
        List<Integer> mid = middle(root);
        System.out.println(Arrays.toString(mid.toArray()));
        for (int i = 0, j = mid.size() - 1; i < j; i++, j--) {
            if (mid.get(i) != mid.get(j))
                return false;
        }
        return true;
    }

    public List<Integer> middle(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if (root != null) {
            if (root.left == null && root.right == null) {
                list.add(root.val);
            } else {
                list.addAll(middle(root.left));
                list.add(root.val);
                list.addAll(middle(root.right));
            }
        }else
            list.add(null);
        return list;
    }

3.2 递归

public boolean isSymmetric(TreeNode root) {
        return root == null || duibi(root.left, root.right);
    }

    public boolean duibi(TreeNode left, TreeNode right) {
        if (left != null && right != null)
            return left.val == right.val && duibi(left.left, right.right) && duibi(left.right, right.left);
        return left == null && right == null;
    }

这是本题我所提交的最好表现,官解的代码几乎也和我的一样,但是这内存消耗怎么才45%,奇怪

在这里插入图片描述

3.3 迭代

public boolean isSymmetric(TreeNode root) {
        if (root != null) {
            LinkedList<TreeNode> treeNodes = new LinkedList<>();
            treeNodes.add(root);
            TreeNode template;
            while (!treeNodes.isEmpty()) {
                template = treeNodes.removeFirst();
                if (template.left == null && template.right == null)
                    continue;
                if (template.left != null && template.right != null) {
                    if (template.left.val != template.right.val)
                        return false;
                    treeNodes.add(new TreeNode(0, template.left.left, template.right.right));
                    treeNodes.add(new TreeNode(0, template.left.right, template.right.left));
                }else
                    return false;
            }
            return true;
        }
        return true;
    }

3.4 对比

利用中序遍历的做法参考意义不大,这里就没有继续写构建二叉树的代码了,就递归和迭代而言,二者的时间复杂度都是O(n),而二者的空间复杂度都是O(n)本质上没有差别,但在迭代中我为了方便直接使用了TreeNode类存储到队列中了,事实上val并没有任何意义的,是一个冗余的参数,这应该也是迭代的内存消耗比递归大的原因
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值