【代码随想录|刷题记录Day15】102.二叉树的层序遍历、226.翻转二叉树、101.对称二叉树

50 阅读2分钟

刷题记录

  102.二叉树的层序遍历

  226.翻转二叉树

  101.对称二叉树

解题过程

1、102.二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

思路: 层序遍历一个二叉树,就是从左到右一层一层的去遍历二叉树。需要借用一个辅助数据结构即队列来实现二叉树的广度优先遍历。队列先进先出,符合一层一层遍历的逻辑。

深度优先搜索

class Solution {
    public List<List<Integer>> res = new ArrayList<List<Integer>>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        dfs(root, 0);
        return res;
    }

    public void dfs(TreeNode node, int deep) {
        if (node == null) {
            return;
        }
        deep++;
        if (res.size() < deep) {
            List<Integer> item = new ArrayList<Integer>();
            res.add(item);
        }
        res.get(deep - 1).add(node.val);
        dfs(node.left, deep);
        dfs(node.right, deep);
    }
}

广度优先搜索

class Solution {
    public List<List<Integer>> res = new ArrayList<List<Integer>>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        bfs(root);
        return res;
    }
    
    public void bfs(TreeNode node) {
        if (node == null) {
            return;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(node);
        while (!queue.isEmpty()) {
            List<Integer> item = new ArrayList<Integer>();
            int len = queue.size();
            while (len > 0) {
                TreeNode tmp = queue.poll();
                item.add(tmp.val);
                if (tmp.left != null) {
                    queue.offer(tmp.left);
                }
                if (tmp.right != null) {
                    queue.offer(tmp.right);
                }
                len--;
            }
            res.add(item);
        }
        return;
    }
}

2、226.翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

思路: 只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果。这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转两次!

递归法

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        swapChildren(root);
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }

    public void swapChildren(TreeNode node) {
        TreeNode tmp = node.left;
        node.left = node.right;
        node.right = tmp;
    }
}

迭代法

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int len = queue.size();
            while (len > 0) {
                TreeNode tmp = queue.poll();
                swapChildren(tmp);
                if (tmp.left != null) {
                    queue.offer(tmp.left);
                }
                if (tmp.right != null) {
                    queue.offer(tmp.right);
                }
                len--;
            }
        }
        return root;
    }

    public void swapChildren(TreeNode node) {
        TreeNode tmp = node.left;
        node.left = node.right;
        node.right = tmp;
    }
}

3、101.对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

思路: 这里要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数也是左子树节点和右子树节点。同样,这里也可以用递归法和迭代法来实现。

递归法

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compareNode(root.left, root.right);
    }

    //递归法
    public boolean compareNode(TreeNode left, TreeNode right) {
        //比较好判断的情况
        if (left == null && right == null) {
            return true;
        } else if (left == null && right != null) {
            return false;
        } else if (left != null && right == null) {
            return false;
        } else if (left.val != right.val) {
            return false;
        }
        //左右节点值相等,继续向下判断
        //内侧
        boolean inCmp = compareNode(left.right, right.left);
        //外侧
        boolean outCmp = compareNode(left.left, right.right);
        return inCmp && outCmp;
    }
}

迭代法

class Solution {
    public boolean isSymmetric(TreeNode root) {
        //迭代法
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root.left);
        queue.offer(root.right);
        while (!queue.isEmpty()) {
            TreeNode leftNode = queue.poll();
            TreeNode rightNode = queue.poll();
            if (leftNode == null && rightNode == null) {
                continue;
            }
            if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) {
                return false;
            }
            //外侧入队
            queue.offer(leftNode.left);
            queue.offer(rightNode.right);
            //内侧入队
            queue.offer(leftNode.right);
            queue.offer(rightNode.left);
        }
        return true; 
    }
}

总结

掌握层序遍历这种遍历方式(借助队列),熟练使用递归法和迭代法解决问题。