当前位置: 首页 > news >正文

代码随想录算法训练营第十五天(二叉树篇)|Leetcode654最大二叉树,Leetcode617合并二叉树,Leetcode700二叉搜索树中的搜索,Leetcode98验证二叉搜索树

Leetcode 654 最大二叉树

题目链接: 最大二叉树

给定一个不含重复元素的整数数组,据此构建一棵最大二叉树,方法如下:

  1. 找出该数组中最大的元素,为其创建一个相应二叉树节点。该元素将该数组分割成两个部分。
  2. 从左部分中选取其中最大的元素,作为当前节点的左孩子节点
  3. 从右部分中选取其中最大的元素,作为当前节点的右孩子节点,重复上述操作直至处理完数组中所有元素。

思路: 整理上述流程,我们知道,我们需要不断找出数组片段中最大值,创建相应节点,并递归处理剩下的区间。

有了昨天处理 从中序遍历和后续遍历构造二叉树(Leetcode 106) 的经验,我们知道,传递区间最佳的方式不是再创建额外的数组,而是传递下标和原数组。因此此处我们采用传递下标的方式解决相应问题。

递归三部曲分析如下:

  1. 递归函数参数与返回值
    递归函数参数为数组整体,以及用于分割数组的相应下标。返回值为创建好的相应二叉树节点
  2. 递归终止条件:
    当给定区间为空时,终止遍历
  3. 每层递归操作:
    找出区间内最大值,利用该最大值将区间分割成两个部分。并将这两个部分的返回值分别作为当前节点的左右子节点。

具体代码实现

class Solution:def buildMaximumBinaryTree(self, nums: List[int], startIdx: int, endIdx: int) -> Optional[TreeNode]:# 由于坚持左闭右开区间,因此当起始下标大于等于终止下标时,停止继续向下递归。if startIdx >= endIdx:return# 找出给定区间内的最大值maxIdx, maxElement = startIdx, nums[startIdx]for i in range(startIdx, endIdx):if nums[i] > maxElement:maxIdx, maxElement = i, nums[i]root = TreeNode(maxElement)leftStartIdx = startIdxleftEndIdx = maxIdxrightStartIdx = maxIdx + 1rightEndIdx = endIdxif leftEndIdx - leftStartIdx > 0:root.left = self.buildMaximumBinaryTree(nums, leftStartIdx, leftEndIdx)if rightEndIdx - rightStartIdx > 0:root.right = self.buildMaximumBinaryTree(nums, rightStartIdx, rightEndIdx)return rootdef constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:# 坚持左闭右开区间root = self.buildMaximumBinaryTree(nums, 0, len(nums))return root

Leetcode 617 合并二叉树

题目链接: 合并二叉树

给定两棵二叉树,将其中的节点进行合并,返回合并后二叉树的根节点。

Example1:

    1           2           3/ \         / \         / \3   2   +   1   3   =   4   5/             \   \     / \   \
5               4   7   5   4   7

当对应节点均存在时,合并后节点的值相当于对应节点值之和
当对应节点存在一个时,合并后节点的值相当于存在的节点值

思路: 合并二叉树时,我们可以在其中一棵二叉树中对节点的值原地进行修改,完成修改后,直接返回对应二叉树的根节点即可。

通过递归三部曲进行分析:

  1. 递归函数参数以及返回值:
    递归函数参数为当前正在遍历的两棵二叉树的对应节点,返回值应该为两棵二叉树合并后的节点
  2. 递归终止条件
    正在遍历的两棵二叉树的相应节点均为空时,终止递归操作。
  3. 每层递归操作
    若两棵二叉树的相应节点均存在,则将节点值相加,创建一个新节点。若仅一棵二叉树的相应节点存在,则在其中一棵二叉树的节点上原地进行修改。

具体代码实现

class Solution:def merge(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:# 对应节点均不存在,返回空if root1 is None and root2 is None:return# 两个节点均存在,将节点值相加if root1 and root2:root1.val += root2.valroot1.left = self.merge(root1.left, root2.left)root1.right = self.merge(root1.right, root2.right)return root1# 返回存在的相应节点if root1:return root1return root2def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:return self.merge(root1, root2)

Leetcode 700 二叉搜索树中的搜索

题目链接: 二叉搜索树中的搜索

在一棵给定的二叉搜索树中,检索给定的值是否出现过。若给定的值在二叉树中出现过则返回相应节点,否则返回空

思路: 首先复习二叉搜索树的概念。
二叉搜索树,即为根节点严格大于左子树中的所有节点,严格小于右子树中所有节点,且左右子树均递归地符合这一要求的一类二叉树。通过二叉搜索树搜索特定的值,时间复杂度为 O(logn)

利用递归三部曲进行分析:

  1. 递归函数参数与返回值:
    递归函数参数为当前遍历的节点以及待查找的目标值,返回值为相应的二叉树节点
  2. 递归终止条件:
    当前节点为空时,返回空节点,终止递归操作。
  3. 每层递归操作:
    比较当前节点的值与目标值,若相等,则返回相应节点,若不相等,则继续深度递归。

具体代码实现

# 递归法
class Solution:def search(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:if root is None:returnif root.val > val:return self.search(root.left, val)if root.val < val:return self.search(root.right, val)return rootdef searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:return self.search(root, val)
# 迭代法
class Solution:def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:from collections import dequeif root is None:returnmyQueue = deque()myQueue.append(root)while myQueue:node = myQueue.popleft()if node.val == val:return node# 利用二叉搜索树中的特性,将相应节点加入到队列中if node.val > val and node.left:myQueue.append(node.left)if node.val < val and node.right:myQueue.append(node.right)return

Leetcode 98 验证二叉搜索树

题目链接: 验证二叉搜索树

给定一棵二叉树,判断该二叉树是否为二叉搜索树。

思路: 本题中一个常见的误区是,直接尝试使用递归法,通过左右子树是否满足二叉搜索树的条件,来判断以当前节点为根节点的二叉树是否为二叉搜索树。然而这种思路并不能够处理以下的情况:

        5/ \4   6/ \3   7

由于 3 < 5,因此该二叉树不是二叉搜索树。

再回忆二叉树的特性,二叉树的根节点大于左子树中的所有节点,小于右子树中的所有节点。因此,我们可以尝试通过中序遍历,获取当前二叉树的数组。若当前二叉树确实是二叉搜索树,则该数组应该是严格递增的。因此,我们可以通过判断当前数组是否严格递增,来判断当前二叉树是否为二叉搜索树。

具体代码实现

class Solution:def inorderTraverse(self, cur: Optional[TreeNode]) -> List[int]:result = []myStack = []if cur is None:return resultmyStack.append([cur, False])while myStack:node, visited = myStack.pop()if visited:result.append(node.val)continueif node.right:myStack.append([cur.right, False])myStack.append([cur, True])if node.left:myStack.append([cur.left, False])return resultdef isValidBST(self, root: Optional[TreeNode]) -> bool:inorder = self.inorderTraverse(root)# 验证中序数组是否严格单调递增for i in range(1, len(inorder)):if inorder[i] <= inorder[i-1]:return Falsereturn True
http://www.sczhlp.com/news/28682/

相关文章:

  • 诗_001
  • 从0.99到1实现一个Windows上的虚拟hid键盘设备
  • 在线设计签名免费网站开封网站设计
  • 网站加密网络推广主要工作内容
  • 企业网站策划书ppt百度提交网站收录查询
  • ui设计需要学编程吗seo优化网页
  • 电商培训学费价格表seo是什么技术
  • 请将uploads里面的所有文件和文件夹上传到你的网站根目录seo服务公司
  • 中国建造师官方网站查询搜索引擎优化工具有哪些
  • 网站模版百度指数平台官网
  • 厦门做企业网站找谁网络推广公司运作
  • 那家公司做网站好google seo是什么啊
  • 做羊水亲子鉴定网站seo优化排名服务
  • 网站图片循环滚动代码国家卫健委:不再发布每日疫情信息
  • 手机版网站如何做图片滚动软文公司代写
  • 怎样做品牌推广网站秘密入口3秒自动进入
  • 20250822
  • 做公司网站需要多少钱太原关键词优化公司
  • Win8系统里dw如何做动态网站百度识图在线入口
  • 网站怎么做切换图片关键词密度查询站长工具
  • 最新网站开发建设教材西安优化外包
  • 广西网站建设软件推广seo优化策略
  • 怎么做免费视频网站吗一年的百度指数
  • 学做网站格式工厂域名注册购买
  • 可以用 我爱乳房做网站名不站长资源平台
  • 淘宝客怎么做其他网站的推广网站服务公司
  • 做网站必须要服务器吗百度荤seo公司
  • 人工智能系统
  • 建筑工程行业网站建设方案ip或域名查询网
  • 滨州做企业网站电商大数据查询平台