树的遍历 之 对称二叉树

284 阅读2分钟

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、题目描述:

题目说的是,给你一个二叉树,你要判断它是否沿中轴线对称。

比如说,给你的二叉树是:

     1
   /   \
  2     2
 / \   / \
4   8 8   4

这棵二叉树是沿中轴线对称的,因此要返回 true。如果我去掉最后这个 41
   /   \
  2     2
 / \   /
4   8 8

就不对称了,这时就要返回 false

二、思路分析:

这道题考察的树的遍历。

思路:

  1. 递归判断左右子树
  2. 非递归方式:用栈来处理

三、AC 代码:

public class LeetCode_101 {

    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }

    // 递归方式:
    // 时间复杂度:整颗树只有最左和最右的两个分支
    // Time o(n), Space o(n), Faster: 100.00%
    public boolean isSymmetric(TreeNode root) {
        if (null == root) {
            return true;
        }
        return isSymmetricNode(root.left, root.right);
    }

    private boolean isSymmetricNode(TreeNode left, TreeNode right) {
        if (left != null && right != null) {
            if (left.val != right.val) return false;
            return isSymmetricNode(left.left, right.right) && isSymmetricNode(left.right , right.left);
        }

        return left == null && right == null;
    }

    // 非递归方式:用栈模拟
    // Time o(n), Space o(n), Faster: 28.14%
    public boolean isSymmetricNode(TreeNode root) {

        if (null == root) return true;

        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root.left);
        stack.push(root.right);

        while (!stack.isEmpty()) {
            TreeNode rightNode = stack.pop();
            TreeNode leftNode = stack.pop();
            if (leftNode == null && rightNode == null) continue;
            if (leftNode == null || rightNode == null) {
                return false;
            }

            if (rightNode.val != leftNode.val) {
                return false;
            }

            stack.push(leftNode.left);
            stack.push(rightNode.right);
            stack.push(leftNode.right);
            stack.push(rightNode.left);
        }
        return true;
    }
}

四、总结:

树的遍历模板

树的遍历有四种:

  1. 前序遍历
  2. 中序遍历
  3. 后序遍历
  4. 层级遍历

这里也可以分为:深度优先遍历(DFS广度优先遍历 (BFS

层级遍历:是为广度优先遍历。

其他遍历:是为深度优先遍历。

1. 前序遍历

void traverse(TreeNode root) {
    if (null == root) return;
    
    // 前序遍历的代码
    
    traverse(root.left);
    traverse(root.right);
}

2. 中序遍历

void traverse(TreeNode root) {
    if (null == root) return;
    
    traverse(root.left);
    
    // 前序遍历的代码
    
    traverse(root.right);
}

3. 后序遍历

void traverse(TreeNode root) {
    if (null == root) return;
    
    traverse(root.left);
    traverse(root.right);
    
    // 前序遍历的代码
}

4. 层级遍历

用队列模拟

void traverse(TreeNode root) {
    if (null == root) return;
    
    // 初始化队列,将 root 加入队列
    Queue<TreeNode> q = new LinkedList<>();
    q.offer(root);
    
    while (!q.isEmpty()) {
        TreeNode cur = q.poll();
        
        // 层级遍历代码
        System.out.println(root.val);
        
        if (cur.left != null) q.offer(cur.left);
        if (cur.right != null) q.offer(cur.right);
    }
}