您的位置:首页 > 健康 > 养生 > 九度互联网站制作效果_施工企业审图ppt_无锡百姓网推广_自动点击竞价广告软件

九度互联网站制作效果_施工企业审图ppt_无锡百姓网推广_自动点击竞价广告软件

2024/12/23 3:35:43 来源:https://blog.csdn.net/rgz147123/article/details/142623042  浏览:    关键词:九度互联网站制作效果_施工企业审图ppt_无锡百姓网推广_自动点击竞价广告软件
九度互联网站制作效果_施工企业审图ppt_无锡百姓网推广_自动点击竞价广告软件

参考文献  代码随想录

一、修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:

输入:root = [1,0,2], low = 1, high = 2
输出:[1,null,2]

示例 2:

输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
输出:[3,2,null,1]

提示:

  • 树中节点数在范围 [1, 104] 内
  • 0 <= Node.val <= 104
  • 树中每个节点的值都是 唯一 的
  • 题目数据保证输入是一棵有效的二叉搜索树
  • 0 <= low <= high <= 104

问题分析

        如果当前的节点小于最小的值,那么根据二次搜索树的性质,左小右大,那么右边很有肯能在范围内,所以要去处理右边的树(不是只处理一个节点)在返回的时候,已经把不在范围内的给去掉了,反之大于最大的值,那么左边很有可能在返回内,所以要向左边遍历。

递归 

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def trimBST(self, root, low, high):""":type root: TreeNode:type low: int:type high: int:rtype: TreeNode"""if root is None:  # 如果为空直接返回Nonereturn Noneif root.val < low: # 当前节点的值小于最小的值,但是根据二次搜索树的性质,左小右大,那么右边很有肯能在范围内,所以要去处理右边的树(不是只处理一个节点)return self.trimBST(root.right, low, high)if root.val > high:return self.trimBST(root.left, low, high)root.left = self.trimBST(root.left, low, high)root.right = self.trimBST(root.right, low, high)return root

迭代

因为二叉搜索树的有序性,不需要使用栈模拟递归的过程。

在剪枝的时候,可以分为三步:

  • 将root移动到[L, R] 范围内,注意是左闭右闭区间
  • 剪枝左子树
  • 剪枝右子树
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def trimBST(self, root, low, high):""":type root: TreeNode:type low: int:type high: int:rtype: TreeNode"""if root is None:  # 如果为空直接返回Nonereturn None# 处理头结点,让root移动到范围内,如果头节点的值while root and (root.val < low or root.val > high): #   要使用while 不一定下一个就满足,有可能存在多个,首先要满足不为空,其次 如果满足不在范围内if root.val < low:  # 如果根节点小于最小的值,那么它的右节点可能存在满足的节点root = root.right # 小于最小值,往右走else:root = root.left # 大于最大值,往左走cur = root # 指针 指向根节点# 此时root已经在范围内,需要处理左孩子while cur:  # 首先不为空一直处理while cur.left and cur.left.val < low:  # 其次左孩子 不为空cur.left = cur.left.right cur = cur.leftcur = root# 此时root已经在范围内,处理右孩子大于R的情况while cur:while cur.right and cur.right.val > high:cur.right = cur.right.leftcur = cur.rightreturn root

二、将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 

平衡

 二叉搜索树。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 按 严格递增 顺序排列

问题分析

        每次分左右数组 ,然后 中间的节点连接,就是,第一次中间的节点是不是 数组长度整除于2然后得到一个值,因为为了保证它是平衡二叉树,然后它是有序的列表,然后左边的链接左边的右边链接右边的。

递归

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def sortedArrayToBST(self, nums):""":type nums: List[int]:rtype: TreeNode"""if not  nums:returnmid = len(nums) // 2left  = nums[: mid]right = nums[mid + 1: ]root = TreeNode(nums[mid])root.left = self.sortedArrayToBST(left)root.right = self.sortedArrayToBST(right)return root

迭代

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def sortedArrayToBST(self, nums):""":type nums: List[int]:rtype: TreeNode"""if not  nums:returnroot = TreeNode(0)  #初始化根节点nodeQue = deque()  # 放遍历的节点leftQue = deque()  # 保存左区间的小标rightQue = deque()  # 保存右区间的下标  nodeQue.append(root)    # 根节点入队列leftQue.append(0)  # 0为左区间小标的初始位置rightQue.append(len(nums)  - 1)  # len(nums) - 1 为右区间下下标的初始位置while nodeQue:curNode = nodeQue.popleft()left = leftQue.popleft()right = rightQue.popleft()mid = (left + right) // 2curNode.val = nums[mid]  # 将mid对应的元素给中间节点if left <= mid - 1: # 处理左curNode.left = TreeNode(0)nodeQue.append(curNode.left)leftQue.append(left)rightQue.append(mid - 1)if right >= mid + 1: # 处理右curNode.right = TreeNode(0)nodeQue.append(curNode.right)leftQue.append(mid + 1)rightQue.append(right)return root

三、把二叉搜索树转换为累加树

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

注意:本题和 1038: . - 力扣(LeetCode) 相同

示例 1:

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

示例 2:

输入:root = [0,null,1]
输出:[1,null,1]

示例 3:

输入:root = [1,0,2]
输出:[3,3,2]

示例 4:

输入:root = [3,2,4,1]
输出:[7,9,4,10]

提示:

  • 树中的节点数介于 0 和 104 之间。
  • 每个节点的值介于 -104 和 104 之间。
  • 树中的所有值 互不相同 。
  • 给定的树为二叉搜索树。

问题分析

        先从右开始累加,这样才能一定大于左的和其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。

为什么变成数组就是感觉简单了呢?

因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。

那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了

递归

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def __init__(self):self.prev = Nonedef convertBST(self, root):""":type root: TreeNode:rtype: TreeNode"""if not root:returnself.convertBST(root.right)if self.prev:root.val += self.prev.valself.prev = rootself.convertBST(root.left)return root

迭代 

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def __init__(self):self.prev = Nonedef convertBST(self, root):""":type root: TreeNode:rtype: TreeNode"""if not root:returnfrom collections import dequestack = deque()stack.append(root)while stack: # 左中右,cur = stack.pop()if cur:if cur.left:stack.append(cur.left)stack.append(cur)stack.append(None)if cur.right:stack.append(cur.right)else:cur = stack.pop()if self.prev:cur.val += self.prev.valself.prev = curreturn root

四、二叉树总结(遍历顺序)

二叉树的理论基础

  • 关于二叉树,你该了解这些! (opens new window):二叉树的种类、存储方式、遍历方式、定义方式

#二叉树的遍历方式

  • 深度优先遍历
    • 二叉树:前中后序递归法 (opens new window):递归三部曲初次亮相
    • 二叉树:前中后序迭代法(一) (opens new window):通过栈模拟递归
    • 二叉树:前中后序迭代法(二)统一风格(opens new window)
  • 广度优先遍历
    • 二叉树的层序遍历 (opens new window):通过队列模拟

#求二叉树的属性

  • 二叉树:是否对称(opens new window)
    • 递归:后序,比较的是根节点的左子树与右子树是不是相互翻转
    • 迭代:使用队列/栈将两个节点顺序放入容器中进行比较
  • 二叉树:求最大深度(opens new window)
    • 递归:后序,求根节点最大高度就是最大深度,通过递归函数的返回值做计算树的高度
    • 迭代:层序遍历
  • 二叉树:求最小深度(opens new window)
    • 递归:后序,求根节点最小高度就是最小深度,注意最小深度的定义
    • 迭代:层序遍历
  • 二叉树:求有多少个节点(opens new window)
    • 递归:后序,通过递归函数的返回值计算节点数量
    • 迭代:层序遍历
  • 二叉树:是否平衡(opens new window)
    • 递归:后序,注意后序求高度和前序求深度,递归过程判断高度差
    • 迭代:效率很低,不推荐
  • 二叉树:找所有路径(opens new window)
    • 递归:前序,方便让父节点指向子节点,涉及回溯处理根节点到叶子的所有路径
    • 迭代:一个栈模拟递归,一个栈来存放对应的遍历路径
  • 二叉树:递归中如何隐藏着回溯(opens new window)
    • 详解二叉树:找所有路径 (opens new window)中递归如何隐藏着回溯
  • 二叉树:求左叶子之和(opens new window)
    • 递归:后序,必须三层约束条件,才能判断是否是左叶子。
    • 迭代:直接模拟后序遍历
  • 二叉树:求左下角的值(opens new window)
    • 递归:顺序无所谓,优先左孩子搜索,同时找深度最大的叶子节点。
    • 迭代:层序遍历找最后一行最左边
  • 二叉树:求路径总和(opens new window)
    • 递归:顺序无所谓,递归函数返回值为bool类型是为了搜索一条边,没有返回值是搜索整棵树。
    • 迭代:栈里元素不仅要记录节点指针,还要记录从头结点到该节点的路径数值总和

#二叉树的修改与构造

  • 翻转二叉树(opens new window)
    • 递归:前序,交换左右孩子
    • 迭代:直接模拟前序遍历
  • 构造二叉树(opens new window)
    • 递归:前序,重点在于找分割点,分左右区间构造
    • 迭代:比较复杂,意义不大
  • 构造最大的二叉树(opens new window)
    • 递归:前序,分割点为数组最大值,分左右区间构造
    • 迭代:比较复杂,意义不大
  • 合并两个二叉树(opens new window)
    • 递归:前序,同时操作两个树的节点,注意合并的规则
    • 迭代:使用队列,类似层序遍历

#求二叉搜索树的属性

  • 二叉搜索树中的搜索(opens new window)

    • 递归:二叉搜索树的递归是有方向的
    • 迭代:因为有方向,所以迭代法很简单
  • 是不是二叉搜索树(opens new window)

    • 递归:中序,相当于变成了判断一个序列是不是递增的
    • 迭代:模拟中序,逻辑相同
  • 求二叉搜索树的最小绝对差(opens new window)

    • 递归:中序,双指针操作
    • 迭代:模拟中序,逻辑相同
  • 求二叉搜索树的众数(opens new window)

    • 递归:中序,清空结果集的技巧,遍历一遍便可求众数集合

    • 二叉搜索树转成累加树(opens new window)

    • 递归:中序,双指针操作累加

    • 迭代:模拟中序,逻辑相同

#二叉树公共祖先问题

  • 二叉树的公共祖先问题(opens new window)
    • 递归:后序,回溯,找到左子树出现目标值,右子树节点目标值的节点。
    • 迭代:不适合模拟回溯
  • 二叉搜索树的公共祖先问题(opens new window)
    • 递归:顺序无所谓,如果节点的数值在目标区间就是最近公共祖先
    • 迭代:按序遍历

#二叉搜索树的修改与构造

注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序,二叉树:找所有路径 (opens new window)也用了前序,这是为了方便让父节点指向子节点。

  • 二叉搜索树中的插入操作(opens new window)
    • 递归:顺序无所谓,通过递归函数返回值添加节点
    • 迭代:按序遍历,需要记录插入父节点,这样才能做插入操作
  • 二叉搜索树中的删除操作(opens new window)
    • 递归:前序,想清楚删除非叶子节点的情况
    • 迭代:有序遍历,较复杂
  • 修剪二叉搜索树(opens new window)
    • 递归:前序,通过递归函数返回值删除节点
    • 迭代:有序遍历,较复杂
  • 构造二叉搜索树(opens new window)
    • 递归:前序,数组中间节点分割
    • 迭代:较复杂,通过三个队列来模拟
  • 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。

  • 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。

  • 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com