遍历二叉树

示例:

输入: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

遍历二叉树的基本思路相关推荐

  1. 层次遍历二叉树(编程之美3.10)

    问题(假定根节点位于第0层) 1. 层次遍历二叉树(每层换行分开) 2. 层次遍历二叉树指定的某层 例如 上图中 1. 1 2 3 4 5 6 7 8 2. 第三层 7 8 可以看出得出第二问的解,第 ...

  2. 更简单的非递归遍历二叉树的方法

    解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出非递归遍历恐非易事.正因为并非易事,所 ...

  3. 遍历二叉树的各种操作(非递归遍历)

    先使用先序的方法建立一棵二叉树,然后分别使用递归与非递归的方法实现前序.中序.后序遍历二叉树,并使用了两种方法来进行层次遍历二叉树,一种方法就是使用STL中的queue,另外一种方法就是定义了一个数组 ...

  4. 编程之美 3.10 分层遍历二叉树

    解题思路: 一开始想到递归,发现用递归很难保证节点的访问顺序.(递归对于先,中,后序遍历都有效,但是对于层次遍历似乎没有找到可行的方法) 按照层次遍历二叉树的做法,通常用一个队列来保证节点按照先入先出 ...

  5. 【转】更简单的非递归遍历二叉树的方法

    [转]更简单的非递归遍历二叉树的方法 解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出 ...

  6. 数据结构入门----遍历二叉树和线索二叉树

    遍历二叉树(Traversing Binary Tree) 二叉树的遍历是指从根结点出发,按照某种次序访问二叉树中的所有结点,使得每个结点被访问一次且仅被访问一次. 实际应用中,查找树中符合条件的结点 ...

  7. 更简单的非递归遍历二叉树

    解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出非递归遍历恐非易事.正因为并非易事,所 ...

  8. 非递归、递归遍历二叉树!

    树的先.中.后.层序的遍历,需要用到栈结构和队结构. 首先来看树本身的定义: typedef char TElemType; typedef struct BiTNode {  TElemType d ...

  9. 栈模拟递归 遍历二叉树的正确写法

    栈模拟递归 遍历二叉树的正确写法 二叉树的生成 树的层次遍历 前中后序遍历的递归实现 关于栈的实现 Reference 对于二叉树的生成,遍历,应该是树这个数据结构需要的基本功,只有真的理解了树的生成 ...

最新文章

  1. wait和notify
  2. A. Case of the Zeros and Ones
  3. sqlite库——C实现,给sqlite数据库添加信息并把信息写入文件,删除日志和库中的日志信息
  4. OpenCV图像处理使用笔记(四)——图像融合
  5. 51`CTO下载中心——我的新爱
  6. 数据存储之 SQLite 数据库操作(三)
  7. linux mongodb启动_linux运维服务篇:MongoDB部署教程分享
  8. linux shell脚本字符串 字段分隔符 存入数组 根据下标取值
  9. 【2018蓝桥省赛A组C/C++】倍数问题(dp+滚动数组)
  10. Python3使用xpath爬取豆丁网文档
  11. 电磁场仿真原理——5. 有限元法(FEM)
  12. 安装element ui
  13. R包survival,survminer生存分析代码
  14. 付呗聚合支付快速教程 分账篇②——分账提现接收方入驻与查询
  15. 计算机无法关闭密码保护,Win7密码保护共享关闭不了怎么办?密码保护共享关不掉的解决方法...
  16. 计算机科学与技术专业前沿技术相关论文,计算机科学与技术专业创新能力的培养途径论文...
  17. Git:gnutls_handshake() failed: A TLS packet with unexpected length was received
  18. LeetCode 299猜数字游戏
  19. Please disable your ad blocker to download
  20. android Phone 距离感应器锁的实现

热门文章

  1. myeclipse的电商系统模板_电商市场分析怎么做?3分钟了解程序员必备分析软件...
  2. mysql yum安装与配置文件_MySQL 8.0 yum安装和配置
  3. oozie mysql_【oozie】将oozie的数据库配置为mysql | 学步园
  4. Docker安装与卸载,配置阿里云镜像加速器
  5. 使用idea创建项目的步骤
  6. vue获取上传进度_vue通过input选取apk文件上传,显示进度条
  7. 计算机图书管理属于计算机应用中的,计算机在图书管理中应用探究.doc
  8. mysql infobright 缺点_infobright、mongodb优劣以及适用范围
  9. vscode 分支列表刷新_分钟将vscode撸成小霸王
  10. java 8 两个list_java集合框架综述