java数据结构与算法刷题-----LeetCode102. 二叉树的层序遍历

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

在这里插入图片描述

1. 法一:广度优先遍历(队列)

解题思路:时间复杂度O(n),空间复杂度O(n)

因为每个结点都要出入队列两次,所以是O(2 * n)的时间复杂度

  1. 先入队列根节点
  2. 则队列中结点个数为第1层结点个数
  3. 出队列根节点,然后将左右孩子入队列
  4. 回到第二不,当前队列中的左右孩子就是第二层的结点个数
  5. 继续第3步,出队列第二层的结点,同时将左右孩子入队列
  6. 以此类推直到队列中没有结点。
  7. 注意,每次出队列时,要先保存当前队列的size(),然后循环输出,否则每出队列一个元素,都会将其孩子入队列,会一直遍历下去,直到队列空。
代码

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();//保存答案
        if(root == null) return result;//如果为空,直接返回空
        Queue<TreeNode> queue = new LinkedList<>();//广度优先,需要队列
        queue.offer(root);//先将根节点入队列
        while(!queue.isEmpty()){//如果队列有值,就说明没遍历完
            List<Integer> level = new ArrayList<>();//保存当前层结点的值
            int currentLevelSize = queue.size();//当前队列中的结点个数,就是当前层的结点个数
            for(int i = 1;i <= currentLevelSize; i++){//将当前层输出
                TreeNode node = queue.poll();//先出队列
                level.add(node.val);//将其值进行遍历
                if(node.left!=null) queue.offer(node.left);//如果有左孩子就入队列
                if(node.right!=null) queue.offer(node.right);//如果有右孩子就入队列
            }//end_for
            result.add(level);//将当前层添加到结果中
        }//end_while
        return result;
    }//end_levelOrder
}//end_Solution

1. 法二:深度优先遍历(递归)

解题思路:时间复杂度O(n),空间复杂度O(n)

每个结点都只访问一次,所以是O(n)的时间复杂度,比上面那个广度优先的实现,每个结点都少存取了一次

  1. 先遍历根结点,设置为0层,并创建一个容器专门保存0层的结点
  2. 然后遍历左孩子,设置为当前层+1层,并创建一个容器专门保存当前层+1层的结点
  3. 递归遍历左孩子完成后,然后遍历右孩子,同样为当前层+1,保存在对应层的容器中
代码

在这里插入图片描述

class Solution {
    private void dfs(TreeNode root, int depth, List<List<Integer>> result) {
        if (root == null) return;//如果当前结点为null,直接返回,出口条件
        //如果当前结点是depth层的第一个结点,那么需要先申请空间,new ArrayList<>()
        if (result.size() == depth) result.add(new ArrayList<>());
        //拿到当前层的链表,保存结点值
        result.get(depth).add(root.val);
        //继续遍历左孩子,但是孩子的层级+1
        dfs(root.left, depth + 1, result);
        //继续遍历右孩子,孩子的层级+1
        dfs(root.right, depth + 1, result);
    }
    //入口程序
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();//保存层序遍历结果
        dfs(root, 0, result);//从第0层开始深度优先
        return result;
    }
}
  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值