代码随想录训练营day15

目录

题目一:二叉树的层序遍历

解法一:迭代法

解法二:递归法

 

题目二:翻转二叉树

解法一:递归法--前序遍历

解法二:迭代法 

题目三:对称二叉树

解法一:递归法--后序遍历

 解法二:迭代法--普通队列


题目一:二叉树的层序遍历

力扣题目链接

题目描述:

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

思路分析:借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑

解法一:迭代法


class Solution {
    public List<List<Integer>> res = new ArrayList<List<Integer>>(); // 二维数组保存最终结果

    public List<List<Integer>> levelOrder(TreeNode root) {
        checkFun(root);
        return res;
    }

    public void checkFun(TreeNode node) {
        if (node == null) return;
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(node); // 结点不为空,则入队列
        
        while (!queue.isEmpty()) { // 队列里没有元素时,终止循环
            List<Integer> list = new ArrayList<>();
            int len = queue.size(); // 每一层的元素个数

            while (len > 0) {
                TreeNode temp = queue.poll(); // 弹出出口元素
                list.add(temp.val);

                if (temp.left != null) queue.offer(temp.left);
                if (temp.right != null) queue.offer(temp.right);
                len--; // 每弹出一个元素,剩余弹出次数减一
            }
            res.add(list); // 每一层的元素以数组的形式存入二维数组
        }
       
    }
}

解法二:递归法


class Solution {
    public List<List<Integer>> res = new ArrayList<List<Integer>>(); // 二维数组保存最终结果

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

    // 在遍历左子树或者右子树的时候,涉及到向上或者向下遍历,为了让递归的过程中的同一层的节点放在同一个列表中,在递归时要记录深度 depth
    public void checkFun(TreeNode node, Integer depth) {
        if (node == null) return;
        depth++; // 表示层数,
       
        if (res.size() < depth) { // 如果depth >= res.size(),说明到下一层了,所以
            // 要先把下一层的list初始化,防止下面add的时候出现空指针异常
            List<Integer> list = new ArrayList<>(); 
            res.add(list);
        }
        // depth表示的是第几层,这里访问到第几层,我们就把数据加入到第几层
        res.get(depth - 1).add(node.val);
        // 当前节点访问完之后,再使用递归的方式分别访问当前节点的左右子节点
        checkFun(node.left, depth);
        checkFun(node.right, depth);
    }
}

 

题目二:翻转二叉树

力扣题目链接

题目描述:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点

思路分析:以树的中间为分割线,把每个节点的左右孩子互换

解法一:递归法--前序遍历


class Solution {
    // DFS:递归三部曲解决
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        swap(root);
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }

    // 实现一个交换指针的swap()
    public void swap(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

解法二:迭代法 


class Solution {
    // BFS
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        
        ArrayDeque<TreeNode> deque = new ArrayDeque<>();
        deque.offer(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            while (size > 0) {
                TreeNode node = deque.poll();
                swap(node);
                if (node.left != null) {
                    deque.offer(node.left);
                }
                if (node.right != null) {
                    deque.offer(node.right);
                }
                size--;
            }
        }
        return root;
    }

    // 实现一个交换指针的swap()
    public void swap(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

题目三:对称二叉树

力扣题目链接

题目描述:给你一个二叉树的根节点 root , 检查它是否轴对称

思路分析:(具体步骤分析见代码随想录

确定需要进行比较的节点,使用递归法中的后序遍历

解法一:递归法--后序遍历


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

    private boolean compare(TreeNode left, TreeNode right) { // 确定递归函数的参数和返回值
        // 确定终止条件
        if (left == null && right != null) {
            return false;
        }
        if (left != null && right == null) {
            return false;
        }

        if (left == null && right == null) {
            return true;
        }
        if (left.val != right.val) {
            return false;
        }
        // 处理单层递归逻辑,向下一层遍历
        // 比较外侧
        boolean compareOutside = compare(left.left, right.right);
        // 比较内侧
        boolean compareInside = compare(left.right, right.left);
        return compareInside && compareOutside;
    }
}

 解法二:迭代法--普通队列


class Solution {
    public boolean isSymmetric(TreeNode root) {
        Queue<TreeNode> deque = new LinkedList<>();
        deque.offer(root.left);
        deque.offer(root.right);
        while (!deque.isEmpty()) {
            TreeNode leftNode = deque.poll();
            TreeNode rightNode = deque.poll();
            if (leftNode == null && rightNode == null) continue;
            if (leftNode == null || rightNode ==null || leftNode.val != rightNode.val) {
                return false;
            }
            deque.offer(leftNode.left);
            deque.offer(rightNode.right);
            deque.offer(leftNode.right);
            deque.offer(rightNode.left);
        }  
        return true;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值