二叉树文章系列:

  1. 二叉树的前序遍历
  2. 二叉树的中序遍历
  3. 二叉树的后序遍历
  4. 二叉树的层序遍历
  5. 二叉树的前序、中序、后序、层序遍历【解法完整版】

本文目录

  • 前言
  • 一、题目
  • 二、思路分析
    • 解法一:广度优先搜索BFS
    • 解法二:深度优先搜索DFS
  • 三、总结

前言

这是[LeetCode精选Top面试]系列文章的第1篇/145篇。
在这个系列中,我们会按照题目类别进行总结。对于每一道题目,会给出一种或多种的算法思路,以及最精炼、最高效的代码。如果代码中涉及到语言上的语法知识,我们也会在知识扩展小节中进行详解。
在每个系列介绍完成之后,我们会再次回顾总结,提炼出通用解法和代码模板。
希望各位持续关注本系列,和我们一起前进,DayDayUp~

一、题目

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

例如:
给定二叉树: [3,9,20,null,null,15,7],

  3/ \
9  20/  \15   7

返回其层次遍历结果:

[[3],[9,20],[15,7]
]

二、思路分析

解法一:广度优先搜索BFS

广度优先搜索是从树的根节点开始,沿着树的宽度来遍历树的节点。如果所有节点均被访问,则算法中止。广度优先搜索通常采用队列来辅助实现。

在题目中要求按照层序遍历,实现逐层地从左向右访问所有的结点。这正好符合广度优先搜索的策略。

我们可以立即想到普通广度优先搜索的模板:

vector<int> bfs(TreeNode* root) {std::vector<int> result;if(!root){return result;}   queue<TreeNode*> q;q.push(root);while(!q.empty()){TreeNode* node = q.front();q.pop();result.emplace_back(node->val);if(node->left){q.push(node->left);}            if(node->right){q.push(node->right);}}return result;
}

但是,这里返回的是一个一维数组,和题目要求的二维数组不一致。因此,我们需要稍作修改,修改内容如下:

  • 在while循环每次遍历时,获取队列的长度N(即队列中的节点个数)
  • 一次性的处理这N个节点,然后再进入下一轮循环。

通过这种修改,确保每次循环时要处理的队列中元素都是本层的元素。

vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;if(!root){return result;}queue<TreeNode*> q;q.push(root);while(!q.empty()){vector<int> tmp;// 每次q.size() 获取的都是队列的长度(一个层的节点个数)for(int i = q.size(); i > 0 ; i--){TreeNode* node = q.front();q.pop();tmp.emplace_back(node->val);if(node->left) q.push(node->left);if(node->right) q.push(node->right);}result.emplace_back(tmp);}return result;}

复杂度分析:

  • 时间复杂度:每个节点元素进队和出队操作各一次,时间复杂度为 O ( N ) O(N) O(N)。
  • 空间复杂度:队列最大存储个数小于等于N,空间复杂度为 O ( N ) O(N) O(N)。

解法二:深度优先搜索DFS

本题也可以使用深度优先搜索来实现。

深度优先搜索是采用栈或者递归来实现。(递归在系统内部也是基于栈来实现)

vector<vector<int>> levelOrder(TreeNode* root) {std::vector<std::vector<int>> res;if(!root) return res;dfs(0, root, res);return res;
}// index 是节点所在层的层索引
void dfs(int index, TreeNode* node, std::vector<std::vector<int>>& res){// node 应该放到res[index]中, 如果res[index]元素不存在, 需要先创建一个if(res.size() < index + 1){res.push_back({});}res[index].emplace_back(node->val);if(node->left){dfs(index+1, node->left, res);}if(node->right){dfs(index+1, node->right, res);}
}

复杂度分析:

  • 时间复杂度:在递归过程中每个节点只访问一次,所以时间复杂度为 O ( N ) O(N) O(N)。
  • 空间复杂度:系统栈的最大存储节点数小于等于N, 所以空间复杂度为 O ( N ) O(N) O(N)。

三、总结

  1. 了解广度优先搜索和深度优先搜索的思想。
  2. 了解两种实现的算法模板,广度优先搜索通常使用队列来实现,深度优先搜索通常使用递归实现。
  3. 能够根据题干的要求,在模板的基础上灵活调整。

BFS和DFS两种方式实现二叉树的层序遍历相关推荐

  1. 417,BFS和DFS两种方式求岛屿的最大面积

    想了解更多数据结构以及算法题,可以关注微信公众号"数据结构和算法",每天一题为你精彩解答.也可以扫描下面的二维码关注 给定一个包含了一些0和1的非空二维数组grid . 一个岛屿是 ...

  2. 二叉树的层序遍历(两种方法实现)

    两种方法实现二叉树的层序遍历 1.说明 二叉树的层序遍历是面试经常会被考察的知识点,甚至要求当场写出实现过程. 层序遍历所要解决的问题很好理解,就是按二叉树从上到下,从左到右依次打印每个节点中存储的数 ...

  3. 32、用队列实现层序遍历-102.二叉树的层序遍历

    题目描述: 给你二叉树的根节点 root ,返回其节点值的 层序遍历 . (即逐层地,从左到右访问所有节点). 思路:之前在剑指Offer中做过 使用队列先入先出的性质,实现层序遍历! DFS(深度优 ...

  4. 五种方式反转二叉树(前序递归和迭代反转,后序递归和迭代反转,层序反转)

    leetcode 226 反转二叉树 题目链接 翻转一棵二叉树. 示例: 输入: 4 / 2 7 / \ / 1 3 6 9 输出: 4 / 7 2 / \ / 9 6 3 1 五种方式实现二叉树的反 ...

  5. c语言返回二叉树的大小,C语言中计算二叉树的宽度的两种方式

    C语言中计算二叉树的宽度的两种方式 二叉树作为一种很特殊的数据结构,功能上有很大的作用!今天就来看看怎么计算一个二叉树的最大的宽度吧. 采用递归方式 下面是代码内容: int GetMaxWidth( ...

  6. 二叉树序列化和反序列化的两种方式

    介绍 二叉树的序列化和反序列化,有两种方式: 第一种方式在将二叉树序列化为数组的时候,需要标记空指针为特殊符号,这样在反序列化的时候,就可以根据这些符号和序列方式来确定一颗二叉树. 第二种方式在序列化 ...

  7. 刷题笔记(十四)--二叉树:层序遍历和DFS,BFS

    目录 系列文章目录 前言 题录 102. 二叉树的层序遍历 BFS DFS_前序遍历 107. 二叉树的层序遍历 II BFS DFS 199. 二叉树的右视图 BFS DFS 637. 二叉树的层平 ...

  8. Dagger2 知识梳理(1) Dagger2 依赖注入的两种方式

    一.资料推荐 最近这几天一直在看有关Dagger2有关的文章,感觉就是这东西真难用.真难懂,数次想要放弃,还好有网上大神的教程帮助,模模糊糊总算能把基本的几个概念跑通了. 这里首先推荐 牛晓伟 的下面 ...

  9. 【剑指offer 07】用迭代和递归两种方法重构二叉树(python实现)

    本文讲解一个经典的面试题,使用 python 通过迭代和递归两种方法重构二叉树. 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字 ...

最新文章

  1. python全栈慕课网靠谱么_全栈和python的区别 ?
  2. javascript实现深克隆的几种方法
  3. 3.1 基础模型-深度学习第五课《序列模型》-Stanford吴恩达教授
  4. 面试题总结15 自己构建一个哈希表
  5. VTK修炼之道55:图形基本操作进阶_表面重建技术(等值面提取)
  6. php显示html表单内容,HTML表单是什么?HTML表单内容的详细介绍(附代码)
  7. 64. magento enable error report
  8. Python使用python-snap7实现西门子PLC通讯
  9. 电路设计——发光二极管限流电阻
  10. 教育培训机构拼团招生小程序公众号
  11. php解密抖音小程序用户手机号/字节跳动小程序thinkphp
  12. JFrame和Swing控件
  13. tensorflow入门教程(二十六)人脸识别(上)
  14. JavaScript同步与异步
  15. 一个隐藏android应用图标的方法
  16. 卡波姆对皮肤的作用副作用_【 卡波姆的副作用】_影响_坏处-大众养生网
  17. JAVA写代码学费,java编程培训班学费是多少
  18. 值得纪念的一天,终于进了大厂
  19. Android开发之安全彻底的修改包名
  20. Python sql插入的简便写法

热门文章

  1. wpf工程中在Xaml文件下添加多个cs文件
  2. 如何在 Chrome 中通过单击右键恢复反向图像搜索
  3. javaweb城市智能公交线路查询系统ssh
  4. 全国普通话计算机测试试题及答案,全国普通话测试试题
  5. google analytics简单总结
  6. java邮件抄送_Java发送邮件遇到的常见需求汇总
  7. excel学习08(笔记自用)
  8. 计算混响时间的意义_计算你录音间的混响时间
  9. 麒麟软件商店使用错误码提示及应对方案
  10. win10IE浏览器运行VBScript脚本语言的简单方法