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

代码随想录第16天:(二叉树)

一、最大二叉树(Leetcode 654)

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
        # 基础条件:当数组只有一个元素时,直接返回该元素构建的二叉树节点
        if len(nums) == 1:
            return TreeNode(nums[0])  # 创建节点并返回

        # 创建一个空节点,用来存放最大值
        node = TreeNode(0)

        # 找到数组中最大的值和对应的下标
        maxValue = 0
        maxValueIndex = 0
        for i in range(len(nums)):
            if nums[i] > maxValue:  # 比较当前元素是否大于已知的最大值
                maxValue = nums[i]  # 更新最大值
                maxValueIndex = i  # 记录最大值的下标

        # 将最大值作为根节点
        node.val = maxValue

        # 处理最大值所在的下标左边的部分,递归构建左子树
        if maxValueIndex > 0:  # 如果左区间非空
            new_list = nums[:maxValueIndex]  # 获取最大值左侧的数组
            node.left = self.constructMaximumBinaryTree(new_list)  # 递归构建左子树

        # 处理最大值所在的下标右边的部分,递归构建右子树
        if maxValueIndex < len(nums) - 1:  # 如果右区间非空
            new_list = nums[maxValueIndex+1:]  # 获取最大值右侧的数组
            node.right = self.constructMaximumBinaryTree(new_list)  # 递归构建右子树

        # 返回构建好的节点(包括其左右子树)
        return node

利用切片+递归:

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
        # 递归终止条件:如果当前数组为空,返回 None,表示没有节点
        if not nums:
            return None
        
        # 找到当前数组中的最大值,并获取其索引
        max_val = max(nums)  # 获取数组中的最大值
        max_index = nums.index(max_val)  # 获取最大值的索引

        # 创建一个新的树节点,节点的值为最大值
        node = TreeNode(max_val)

        # 递归构建左子树:数组中最大值左侧的部分
        node.left = self.constructMaximumBinaryTree(nums[:max_index])
        
        # 递归构建右子树:数组中最大值右侧的部分
        node.right = self.constructMaximumBinaryTree(nums[max_index+1:])

        # 返回当前节点,该节点是一个包含左、右子树的树节点
        return node

二、合并二叉树(Leetcode 617)

class Solution:
    def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        # 递归终止条件: 
        #  但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None. 
        if not root1: 
            return root2
        if not root2: 
            return root1
        # 上面的递归终止条件保证了代码执行到这里root1, root2都非空. 
        root = TreeNode() # 创建新节点
        root.val += root1.val + root2.val# 中
        root.left = self.mergeTrees(root1.left, root2.left) #左
        root.right = self.mergeTrees(root1.right, root2.right) # 右
        
        return root  

三、二叉搜索树中的搜索(Leetcode 700)

递归法:

class Solution:
    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        # 如果当前节点为空(即树为空)或当前节点的值等于目标值
        # 则返回当前节点(即找到了目标值的节点)
        if not root or root.val == val:
            return root
        
        # 如果当前节点的值大于目标值,则目标值应该在当前节点的左子树中
        if root.val > val:
            return self.searchBST(root.left, val)
        
        # 如果当前节点的值小于目标值,则目标值应该在当前节点的右子树中
        if root.val < val:
            return self.searchBST(root.right, val)

迭代法:

class Solution:
    def searchBST(self, root: [TreeNode], val: int) -> TreeNode:
        # 当当前节点存在时,继续迭代查找
        while root:
            # 如果当前节点的值大于目标值,目标节点应该在左子树
            if root.val > val:
                root = root.left
            # 如果当前节点的值小于目标值,目标节点应该在右子树
            elif root.val < val:
                root = root.right
            # 如果当前节点的值等于目标值,返回当前节点
            else:
                return root
        # 如果没有找到目标值的节点,返回 None
        return None

四、验证二叉搜索树(Leetcode 98)


思路:二叉搜索树的中序遍历结果为递增有序数组

class Solution:
    def __init__(self):
        self.vec = []  # 用于存储二叉树中序遍历的结果
    
    # 中序遍历二叉树
    def traversal(self, root):
        if root is None:  # 基本条件:如果当前节点为空,则返回
            return
        self.traversal(root.left)  # 递归遍历左子树
        self.vec.append(root.val)  # 将当前节点的值加入到vec列表中
        self.traversal(root.right)  # 递归遍历右子树

    # 判断是否是有效的二叉搜索树
    def isValidBST(self, root):
        self.vec = []  # 清空数组
        self.traversal(root)  # 执行中序遍历,填充vec
        
        # 检查中序遍历的结果是否严格递增
        for i in range(1, len(self.vec)):
            # 注意要小于等于,搜索树里不能有相同元素
            if self.vec[i] <= self.vec[i - 1]:  # 如果不严格递增,说明不是有效的BST
                return False
        return True  # 如果遍历完都没有问题,说明是有效的BST

误区:

if (root.val > root.left.val and root.val < root.right.val):
    return True

二叉搜索树的根节点比左边所有子树的值都大,比所有右子树的值都要小,上述判断语句没有考虑到整体

迭代法:中序遍历判断结果是否递增

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        stack = []  # 初始化栈,用来模拟递归的过程
        cur = root  # 当前节点指针,从根节点开始遍历
        pre = None  # 记录前一个节点,初始化为 None
        
        # 当当前节点不是 None,或者栈中还有待处理的节点时继续遍历
        while cur or stack:
            if cur:
                # 如果当前节点不为空,将当前节点压入栈
                stack.append(cur)
                # 然后访问当前节点的左子树
                cur = cur.left  
            else:
                # 如果当前节点为空,弹出栈顶节点并处理
                cur = stack.pop()  # 弹出栈顶节点
                # 如果前一个节点存在,且当前节点的值不大于前一个节点的值,返回 False
                if pre and cur.val <= pre.val:
                    return False
                # 更新前一个节点为当前节点
                pre = cur
                # 访问当前节点的右子树
                cur = cur.right  
        
        # 如果遍历完成后没有违反 BST 规则,返回 True
        return True

相关文章:

  • Jieba分词的原理及应用(三)
  • mysql:重置表自增字段序号
  • 硬件设计-MOS管快速关断的原因和原理
  • linux 添加唤醒词
  • 【在Node.js项目中引入TypeScript:提高开发效率及框架选型指南】
  • 【软考系统架构设计师】软件工程
  • 【蓝桥杯】第十六届蓝桥杯 JAVA B组记录
  • spring--声明式事务
  • 编译 OpenCV 时,cmake 找到 TBB 的方法
  • WPF设计标准学习记录27
  • windows安装fastbev环境时,安装mmdetection3d出现的问题总结
  • Bootstrap4 卡片
  • thingsboard3.9.1编译问题处理
  • 【算法】 欧拉函数与欧拉降幂 python
  • 从零开始开发纯血鸿蒙应用之语音输入
  • Transformer模型设置评价模式:Dropout 停止随机丢弃神经元,从而保证每次输入得到的输出是确定的
  • AI代理是大模型实现可扩展智能自动化的关键
  • Flutter:图片在弹窗外部的UI布局
  • Java学习手册:Java集合框架详解
  • 基于 Maven 构建的 Thingsboard 3.8.1 项目结构
  • 西安网站设计学校/开一个免费网站
  • pinterest的优点/seo 的作用和意义
  • 自己做充值网站/重庆seo点击工具
  • 中国建设银行复核网站/新闻头条 今天
  • 男人和女人做羞羞的免费网站/灰色广告投放平台
  • 网站建设哪里便宜/成都新站软件快速排名