遍历二叉树的基本思路
遍历二叉树
示例:
输入:2/ \1 3输出:
1
输入:1/ \2 3/ / \4 5 6/7输出:
7
思路:
思路1:DFS深度递归遍历,时间O(n) 空间O(h),h为数的高度
还是DFS递归,与递归的遍历形式基本一样,记录下当前的深度depth,同时用一个全局变量记录最大深度
当刚遍历到新的一层的时候,depth会增加1,此时比较第一次depth > maxdepth的时候
对应的node.val就是那层的第一个节点
同理,也能找出最右下角的值,只需把两个dfs调换位置
思路2:BFS广度循环遍历,时间O(n) 空间O(b),b为树的宽度
BFS用循环就已经很好理解了,没必要写成递归形式
每一轮记录下当前层的第一个值,最后返回即可
py解法:
#python3
# DFS深度递归遍历,时间O(n) 空间O(h),h为数的高度
class Solution:def findBottomLeftValue(self, root: TreeNode) -> int:def dfs(root, depth):if not root: returnif depth > self.maxdepth:self.maxdepth = depthself.res = root.val dfs(root.left, depth+1)dfs(root.right, depth+1)self.maxdepth, self.res = -1, 0dfs(root, 0)return self.res# BFS广度循环遍历,时间O(n) 空间O(b),b为树的宽度
class Solution:def findBottomLeftValue(self, root: TreeNode) -> int:if not root: return []cur, res = [root], Nonewhile cur:layer, res = [], cur[0].valfor node in cur:if node.left: layer.append(node.left)if node.right: layer.append(node.right)cur = layerreturn res
java解法:
考察二叉树的层序遍历,也就是广度优先遍历,广度优先遍历的基本思路为:每次将根节点的相邻节点放入一个容器(队列)中,遍历到目前为止容器中所有节点,并在遍历的过程中再将每个节点的所有相邻节点放入容器中,重复此过程直到队列为空。
import java.util.Queue;
import java.util.LinkedList;
import java.util.ArrayList;
class Solution {public int findBottomLeftValue(TreeNode root) {ArrayList<ArrayList<Integer>> result = new ArrayList<>();Queue<TreeNode> queue = new LinkedList<>();queue.add(root);while(!queue.isEmpty()){int size = queue.size();ArrayList<Integer> list = new ArrayList<>();for(int i = 0; i<size; i++){TreeNode temp = queue.poll();list.add(temp.val);if(temp.left != null){queue.add(temp.left);}if(temp.right != null){queue.add(temp.right);}}result.add(list);}return result.get(result.size()-1).get(0);}
}
仅仅击败的23.46%,太慢了。那有什么改进的思路呢?
通过我们细致的观察就可以发现,题目要求最后一层的左端第一个节点,其实也就是右端的最后一个节点。那这样的话,我们何不在层序遍历的时候直接从每层的右边开始遍历,那遍历的最后一个点也就是我们想要的答案了。而且这样我们就不用去记录深度了。
import java.util.Queue;
import java.util.LinkedList;
class Solution {public int findBottomLeftValue(TreeNode root) {int result = 0;Queue<TreeNode> queue = new LinkedList<>();queue.add(root);while(!queue.isEmpty()){TreeNode temp = queue.poll();//每次记录一下结果result = temp.val;//先放右边if(temp.right != null){queue.add(temp.right);}//再放左边if(temp.left != null){queue.add(temp.left);}}return result;}
}
C++解法:
class Solution {public:int findBottomLeftValue(TreeNode* root) {queue<TreeNode*> q;q.push(root);TreeNode* last = root;TreeNode* nlast = nullptr;vector<int> level_first; //每层第一个节点int res = 0;while (!q.empty()){TreeNode* node = q.front();q.pop();if (level_first.empty()) {level_first.push_back(node->val);}if (node->left){q.push(node->left);nlast = node->left;}if (node->right){q.push(node->right);nlast = node->right;}if (node == last){last = nlast;level_first.clear();}if(q.empty()) //最后一层 最后一个节点{res = level_first.front();}}return res;}//从右到左 找最后一个节点int findBottomLeftValue(TreeNode* root) {queue<TreeNode*> q;q.push(root);int res = 0;while (!q.empty()){TreeNode* node = q.front();q.pop();if (node->right){q.push(node->right);}if (node->left){q.push(node->left);}if(q.empty()) //最后一个节点{res = node->val;}}return res;}
};
返回每层最大的数
按层入坑,然后更新最大值。关键就在如何在更新最大值的时候判断当前坑位(层数)是否已经存在,即第一次遇到最新层的处理。
申请足够大的数组,初始化为最小值(因题目节点可能存在负数),因而解决第一次遇到最新层的问题。同时用超大数组操作还需要返回总元素个数(层数),也就是大于最大层数后面的元素都抛弃。
# py代码参考提交成功范例
class Solution:def largestValues(self, root: TreeNode) -> List[int]:ans = []def help(root: TreeNode, level: int) -> None:if not root: returnif len(ans) <= level: # 遇到最新一层ans.append(float('-inf'))ans[level] = max(ans[level], root.val)help(root.left, level + 1)help(root.right, level + 1)help(root, 0) # 初始化为0问题!return ans
遍历二叉树的基本思路相关推荐
- 层次遍历二叉树(编程之美3.10)
问题(假定根节点位于第0层) 1. 层次遍历二叉树(每层换行分开) 2. 层次遍历二叉树指定的某层 例如 上图中 1. 1 2 3 4 5 6 7 8 2. 第三层 7 8 可以看出得出第二问的解,第 ...
- 更简单的非递归遍历二叉树的方法
解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出非递归遍历恐非易事.正因为并非易事,所 ...
- 遍历二叉树的各种操作(非递归遍历)
先使用先序的方法建立一棵二叉树,然后分别使用递归与非递归的方法实现前序.中序.后序遍历二叉树,并使用了两种方法来进行层次遍历二叉树,一种方法就是使用STL中的queue,另外一种方法就是定义了一个数组 ...
- 编程之美 3.10 分层遍历二叉树
解题思路: 一开始想到递归,发现用递归很难保证节点的访问顺序.(递归对于先,中,后序遍历都有效,但是对于层次遍历似乎没有找到可行的方法) 按照层次遍历二叉树的做法,通常用一个队列来保证节点按照先入先出 ...
- 【转】更简单的非递归遍历二叉树的方法
[转]更简单的非递归遍历二叉树的方法 解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出 ...
- 数据结构入门----遍历二叉树和线索二叉树
遍历二叉树(Traversing Binary Tree) 二叉树的遍历是指从根结点出发,按照某种次序访问二叉树中的所有结点,使得每个结点被访问一次且仅被访问一次. 实际应用中,查找树中符合条件的结点 ...
- 更简单的非递归遍历二叉树
解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出非递归遍历恐非易事.正因为并非易事,所 ...
- 非递归、递归遍历二叉树!
树的先.中.后.层序的遍历,需要用到栈结构和队结构. 首先来看树本身的定义: typedef char TElemType; typedef struct BiTNode { TElemType d ...
- 栈模拟递归 遍历二叉树的正确写法
栈模拟递归 遍历二叉树的正确写法 二叉树的生成 树的层次遍历 前中后序遍历的递归实现 关于栈的实现 Reference 对于二叉树的生成,遍历,应该是树这个数据结构需要的基本功,只有真的理解了树的生成 ...
最新文章
- wait和notify
- A. Case of the Zeros and Ones
- sqlite库——C实现,给sqlite数据库添加信息并把信息写入文件,删除日志和库中的日志信息
- OpenCV图像处理使用笔记(四)——图像融合
- 51`CTO下载中心——我的新爱
- 数据存储之 SQLite 数据库操作(三)
- linux mongodb启动_linux运维服务篇:MongoDB部署教程分享
- linux shell脚本字符串 字段分隔符 存入数组 根据下标取值
- 【2018蓝桥省赛A组C/C++】倍数问题(dp+滚动数组)
- Python3使用xpath爬取豆丁网文档
- 电磁场仿真原理——5. 有限元法(FEM)
- 安装element ui
- R包survival,survminer生存分析代码
- 付呗聚合支付快速教程 分账篇②——分账提现接收方入驻与查询
- 计算机无法关闭密码保护,Win7密码保护共享关闭不了怎么办?密码保护共享关不掉的解决方法...
- 计算机科学与技术专业前沿技术相关论文,计算机科学与技术专业创新能力的培养途径论文...
- Git:gnutls_handshake() failed: A TLS packet with unexpected length was received
- LeetCode 299猜数字游戏
- Please disable your ad blocker to download
- android Phone 距离感应器锁的实现
热门文章
- myeclipse的电商系统模板_电商市场分析怎么做?3分钟了解程序员必备分析软件...
- mysql yum安装与配置文件_MySQL 8.0 yum安装和配置
- oozie mysql_【oozie】将oozie的数据库配置为mysql | 学步园
- Docker安装与卸载,配置阿里云镜像加速器
- 使用idea创建项目的步骤
- vue获取上传进度_vue通过input选取apk文件上传,显示进度条
- 计算机图书管理属于计算机应用中的,计算机在图书管理中应用探究.doc
- mysql infobright 缺点_infobright、mongodb优劣以及适用范围
- vscode 分支列表刷新_分钟将vscode撸成小霸王
- java 8 两个list_java集合框架综述