文章目录

  • 二叉树的中序遍历(94E)
  • 验证二叉搜索树(98M)
  • 二叉树的层序遍历(102M)
  • 从前序与中序遍历序列构造二叉树(105M)
  • 二叉树中的最大路径和(124H)
  • 二叉树的前序遍历(144E)
  • 二叉树的后序遍历(145E)
  • 二叉搜索树的最近公共祖先(235E)
  • 二叉树的最近公共祖先(236M)

二叉树的中序遍历(94E)

94. 二叉树的中序遍历

难度:【简单】

方法一:递归
树本身就有递归的特性,因此递归方法最简单,这里直接放上代码,需要说明的是,中序遍历,前序遍历和后序遍历可采用相同的代码模板完成实现。

代码如下:

class Solution:def inorderTraversal(self, root: TreeNode) -> List[int]:if not root:return []return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)

时间复杂度:O(n),n 为树的节点个数
空间复杂度:O(h),h 为树的高度

方法二:迭代

需要一个栈的空间,先用指针找到每颗子树的最左下角,然后进行进出栈的操作。

代码如下:

class Solution:def inorderTraversal(self, root: TreeNode) -> List[int]:if not root:return []stack = []res = []cur = rootwhile stack or cur:while cur:stack.append(cur)cur = cur.leftcur = stack.pop()res.append(cur.val)cur = cur.rightreturn res

时间复杂度:O(n),n 为树的节点个数
空间复杂度:O(h),h 为树的高度

验证二叉搜索树(98M)

98. 验证二叉搜索树

难度:【中等】

思路一:递归中序遍历,判断其是否升序且无重复值。
判断方法:order == list(sorted(set(order)))
代码如下:

class Solution:def isValidBST(self, root: TreeNode) -> bool:inorder = self.inorder(root)return inorder == list(sorted(set(inorder)))def inorder(self,root):if not root:return []return self.inorder(root.left) + [root.val] + self.inorder(root.right)

思路二:迭代中序遍历,在遍历过程中判断前序节点是否小于当前节点。

代码如下:

class Solution:def isValidBST(self, root: TreeNode) -> bool:stack= []pre = Nonecur = rootwhile cur or stack:while cur:stack.append(cur)cur = cur.leftcur = stack.pop()if pre and pre.val >= cur.val:return Falsepre = curcur = cur.rightreturn True

思路三:递归中序遍历,在递归过程中判断前序节点是否小于当前节点。

代码如下:

class Solution:def isValidBST(self, root: TreeNode) -> bool:self.pre = Nonedef isBST(root):if not root:return Trueif not isBST(root.left):return Falseif self.pre and self.pre.val >= root.val:return Falseself.pre = root#print(root.val)return  isBST(root.right)return isBST(root)

二叉树的层序遍历(102M)

102. 二叉树的层序遍历
难度:【中等】
参考:
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/python3-er-cha-shu-ceng-xu-bian-li-by-jo-nlx3/
思路:BFS
1、如果 root 为空,直接返回 [ ]
2、定义一个数组queue,并将 root 添加到 queue中,再定义一个res 数组保存结果
3、遍历 当前层 queue 的每个左子节点,右子节点,入队列,且要把 queue 更新成当前层的孩子节点列表,直到 queue 为空。

代码如下:

class Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:if not root:return []queue = [root]res = []while queue:res.append([node.val for node in queue])l1 = []for node in queue: if node.left:l1.append(node.left)if node.right:l1.append(node.right)queue = l1return res

从前序与中序遍历序列构造二叉树(105M)

105. 从前序与中序遍历序列构造二叉树

难度:【中等】

该题还未深入研究。

代码:

class Solution:def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:def myBuildTree(preorder_left: int, preorder_right: int, inorder_left: int, inorder_right: int):if preorder_left > preorder_right:return None# 前序遍历中的第一个节点就是根节点preorder_root = preorder_left# 在中序遍历中定位根节点inorder_root = index[preorder[preorder_root]]# 先把根节点建立出来root = TreeNode(preorder[preorder_root])# 得到左子树中的节点数目size_left_subtree = inorder_root - inorder_left# 递归地构造左子树,并连接到根节点# 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素root.left = myBuildTree(preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1)# 递归地构造右子树,并连接到根节点# 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素root.right = myBuildTree(preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right)return rootn = len(preorder)# 构造哈希映射,帮助我们快速定位根节点index = {element: i for i, element in enumerate(inorder)}return myBuildTree(0, n - 1, 0, n - 1)

二叉树中的最大路径和(124H)

124. 二叉树中的最大路径和

难度:【困难】

思路:递归
本质就是后序遍历,对于一个二叉树节点,计算左子树和右子树的最大路径和,再加上自己的值,得到该节点的最大路径和。

  • 首先实现一个简化函数maxGain(node),计算二叉树中一个节点的最大贡献值
  • 计算二叉树的最大路径和,对于二叉树中的一个节点,该节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值,如果子节点的最大贡献值为正,则计入该节点的最大路径和,否则不计入该节点的最大路径和
  • 维护一个全局变量maxSum存储最大路径和,在递归过程中更新maxSum的值。

代码:

class Solution:def __init__(self):self.maxSum = float("-inf")def maxPathSum(self, root: TreeNode) -> int:def maxGain(node):if not node:return 0leftGain = max(maxGain(node.left),0)rightGain = max(maxGain(node.right),0)priceNewPath = node.val + leftGain + rightGainself.maxSum = max(self.maxSum, priceNewPath)return node.val + max(leftGain, rightGain)maxGain(root)return self.maxSum

时间复杂度:O(N)
空间复杂度:O(N)

二叉树的前序遍历(144E)

144. 二叉树的前序遍历

难度:【简单】

方法一:递归
树本身就有递归的特性,因此递归方法最简单,这里直接放上代码,需要说明的是,中序遍历,前序遍历和后序遍历可采用相同的代码模板完成实现。

class Solution:def preorderTraversal(self, root: TreeNode) -> List[int]:if not root:return []return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)

时间复杂度:O(n),n 为树的节点个数
空间复杂度:O(h),h 为树的高度

方法二:迭代

代码如下:

class Solution:def preorderTraversal(self, root: TreeNode) -> List[int]:if not root:return []stack = []res = []cur = rootwhile stack or cur:while cur:stack.append(cur)res.append(cur.val)cur = cur.leftcur = stack.pop()cur = cur.rightreturn res

时间复杂度:O(n),n 为树的节点个数
空间复杂度:O(h),h 为树的高度

二叉树的后序遍历(145E)

145. 二叉树的后序遍历

难度:【中等】

方法一:递归
树本身就有递归的特性,因此递归方法最简单,这里直接放上代码,需要说明的是,中序遍历,前序遍历和后序遍历可采用相同的代码模板完成实现。

代码如下:

class Solution:def postorderTraversal(self, root: TreeNode) -> List[int]:if not root:return []return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + [root.val]

时间复杂度:O(n),n 为树的节点个数
空间复杂度:O(h),h 为树的高度

方法二:迭代

注意:该代码是基于前序遍历改来的,由于前序遍历是中左右,后序遍历是左右中,所以只需要写出中右左,再进行反转即可得到左右中。

代码如下;

class Solution:def postorderTraversal(self, root: TreeNode) -> List[int]:if not root:return []res = []stack = []cur = rootwhile stack or cur:while cur:stack.append(cur)res.append(cur.val)cur = cur.rightcur = stack.pop() cur = cur.leftreturn res[::-1]

时间复杂度:O(n),n 为树的节点个数
空间复杂度:O(h),h 为树的高度

二叉搜索树的最近公共祖先(235E)

235. 二叉搜索树的最近公共祖先

难度:【简单】

第一种思路:对于两个节点,从下往上找,依次找到对应的路径,在对两个路径找到相同的结点。(不好实现)

第二种思路:从根节点找到两个结点对应的路径,对两个路径进行查找。
代码如下:

第三种思路:采用递归的方法进行查找。
代码如下:

class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if p.val < root.val > q.val:return self.lowestCommonAncestor(root.left, p, q)elif p.val > root.val < q.val:return self.lowestCommonAncestor(root.right, p, q)else:return root

第四种:非递归的写法,while循环来完成。

代码如下:

class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':while root:if p.val < root.val > q.val:root = root.leftelif p.val > root.val < q.val:root = root.rightelse:return root

二叉树的最近公共祖先(236M)

236. 二叉树的最近公共祖先

难度:【中等】

第一种思路:对于两个节点,从下往上找,依次找到对应的路径,在对两个路径找到相同的结点。(不好实现)

第二种思路:从根节点找到两个结点对应的路径,对两个路径进行查找。

第三种思路:采用递归的方法进行查找。
解法:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/236-er-cha-shu-de-zui-jin-gong-gong-zu-xian-hou-xu/
代码如下:

class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if not root:return rootif root == p or root == q:return rootleft = self.lowestCommonAncestor(root.left, p, q)right = self.lowestCommonAncestor(root.right, p, q)if not left: return rightif not right: return leftreturn root

Leetcode-树相关推荐

  1. LeetCode——树:层次遍历、前中后序遍历

    LeetCode--树:层次遍历.前中后序遍历 目录 层次遍历 二叉树的层平均值 找树左下角的值 前中后序遍历 概述 非递归实现二叉树的前序遍历 非递归实现二叉树的中序遍历 非递归实现二叉树的后序遍历 ...

  2. LeetCode——树:递归

    LeetCode--树:递归 目录 概述 树的高度(LeetCode104) 平衡树(LeetCode110) 两节点的最长路径(LeetCode543) 翻转树(LeetCode226) 归并两棵树 ...

  3. leetcode: 树

    文章目录 01二叉树的镜像 02 对称的二叉树 03 从上到下打印二叉树 II 04二叉树的深度 05 判断是否是平衡二叉树 06 重建二叉树 07 二叉树的最近公共祖先 08 二叉搜索树的第k大节点 ...

  4. LeetCode——树:BST

    BST 目录 概述 修剪二叉查找树(LeetCode669) 寻找二叉查找树的第k个元素(LeetCode230) 把二叉查找树每个节点的值都加上比它大的节点的值 二叉查找树的最近公共祖先(LeetC ...

  5. 一刷leetcode——树

    94. Binary Tree Inorder Traversal 题意:中序遍历二叉树 我的思路:递归水题 我的代码: /*** Definition for a binary tree node. ...

  6. leetcode树之二叉树分裂子树

    文章目录 1145.二叉树着色游戏 1339.分裂二叉树的最大乘积 1145.二叉树着色游戏 有两位极客玩家参与了一场「二叉树着色」的游戏.游戏中,给出二叉树的根节点 root,树上总共有 n 个节点 ...

  7. 图解:数据结构中的6种「树」,柠檬问你心中有数吗?

    数据结构这门课程是计算机相关专业的基础课,数据结构指的是数据在计算机中的存储.组织方式. 我们在学习数据结构时候,会遇到各种各样的基础数据结构,比如堆栈.队列.数组.链表.树...这些基本的数据结构类 ...

  8. 备战秋招 |《百面机器学习》算法+leetcode开班报名!

    算法面试刷题班推荐: 以<百面机器学习>为教材 结合leetcode筛选刷题 秋招已经开始了!时间紧迫,也许别人已经得到offer了,你却还在不知所措?(文末重金招聘讲师) 六月份基本都是 ...

  9. 仅剩3天 | 带学《百面机器学习》葫芦书,算法+leetcode一应俱全

    或许你只要比别人准备多一点,你就可以在群体中脱颖而出. 年后基本都是春招和社招的高峰期,但好岗位招聘人数和应聘人数简直堪比春运抢票. 你总在抱怨"为什么别人机会那么好,能抢到你想要的名额?& ...

  10. 图解 6 种「树」,你心中有数吗。。。

    数据结构这门课程是计算机相关专业的基础课,数据结构指的是数据在计算机中的存储.组织方式. 我们在学习数据结构时候,会遇到各种各样的基础数据结构,比如堆栈.队列.数组.链表.树...这些基本的数据结构类 ...

最新文章

  1. 《评人工智能如何走向新阶段》后记(再续8)
  2. python装饰器实例-python 装饰器的使用示例
  3. python资料百度云-Java+Python+前端 学习资料大全 百度云盘
  4. Hdu 2522 hash
  5. Java实现MD5加密和文件校验
  6. gdb / 调试进入 so 库的方法
  7. java iterator map_Java循环遍历输出map方法
  8. des算法明文IP置换C语言编程,求助攻:C语言DES算法的实现程序有问题
  9. 《父亲家书》选:母亲的手摔伤了
  10. BZOJ2957 楼房重建
  11. 使用RQShineLabel
  12. angularjs1.x版本,父子组件之间的双向绑定
  13. python数字类型及运算_Python基础教程:运算符以及数据类型解析
  14. 安卓计步器是如何实现计步的
  15. mapgis坡度分析_gis气候分析图_用MAPGIS做城市气候的分析需要什么类型的数据可以从哪下载_滁州气象...
  16. zoj 3332 Strange Country II
  17. 亲属卡额度是什么意思_2019信用卡权益总结之十二:附属卡
  18. 百度Java出现:“现在学java的都是傻子”相关搜索!
  19. [WDS] Disconnected解决方法
  20. 为 VS 2012 打包 MSDN 在线文档为磁盘安装源

热门文章

  1. 【排序算法】快速排序-迭代方法
  2. java day11【final、权限、内部类、引用类型】
  3. vue 父子之间通信及非父子之间通信
  4. php的public、protected、private三种访问控制模式的区别
  5. 20180513 实参 形参 数组
  6. Javaworkers团队第五周项目总结
  7. 隐藏TreeView中SiteMap的根节点
  8. ASP.NET MVC上传限制
  9. 窗口及元素尺寸大小位置获取方法记录
  10. es6语法图片切换demo