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

分治思想--python

分治

一、几个能用分治解决的判断依据:

  • 问题可以分解:原问题可以分解为规模更小、类似的子问题,可以用同样方式递归进行划分。
  • 子问题独立:子问题之间没有重叠互不重叠,可以独立解决。
  • 子问题的解可以合并:原问题的解通过合并子问题的解得来。

分治可以有效的解决算法问题,可以提升算法的效率,因为分治的子问题相互独立,因此可以并行解决,也就是说分治不仅仅可以降低算法的时间复杂度,还有利于操作系统的并行优化。

二、常见的分治应用:

  • 二分查找:将有序数组从中点索引处分为两个部分,然后根据目标值与中间元素值比较结果,决定排除哪一半区间,并在剩余区间执行相同的二分操作。
  • 归并排序:把已经排好序的子序列进行合并,得到一个完整的有序序列,相对于先排序一片区域等排序完区域再拼接。
  • 快速排序:从数列中选出一个元素,作为一个基准,重新排序,所有比基准小的放在数组左边,所有比基准大的数字放在数组右边,在这个分区结束后,这个基准数字就在数组的最中间,这个被称为分区操作,利用递归把小于基准的子序列和大于基准的子序列进行排序,最终得到一个完整的排序数组。
  • 桶排序:设定一个定量的数组作为空桶,遍历数组,将数据放到对应的桶中,对每个不是空的桶进行排序,从每个非空桶中取出数据进行拼接,得到完整的排序数据。
  • 树:二叉树,AVL树等

三、二分查找:

  • 问题可以分解:二分查找递归的将原问题分解为子问题,这是通过比较中间元素和目标元素来实现。
  • 子问题独立:在二分查找中,每轮只处理一个问题,它不受其他子问题的影响。
  • 子问题的解不需要合并:二分查找是为了找到一个特定元素,因此不需要将子问题的解进行合并,当子问题得到解决时,原问题也会被解决。
def dfs(nums: list[int], target: int, left: int, right: int):# 终结条件,区间不存在后返回-1if left > right:return -1# 计算中间点midmid = (left + right) // 2# 如果目标值大于中间值if nums[mid] < target:# 继续递归return dfs(nums, target, mid + 1, right)# 如果目标值小于中间值elif nums[mid] > target:# 继续递归return dfs(nums, target. left. mid - 1)# 找到目标值else:# 返回目标索引return middef binary_search(nums: list[int], target: int):lenth = len(nums)return def(nums, target, 0, lenth - 1)

四、恢复二叉树:

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

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

从中序与后序遍历序列构造二叉树

https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

  • 问题可以分解:将问题分解为构建左子树,构建右子树。每次将树分解成更小的子树,直到达到空子树为止。
  • 子问题独立:左子树和右子树相互独立,没有交集。构建左子树只需要关注中序遍历和前序遍历中与左子树对应的部分,右子树同理。
  • 子问题的解可以合并:得到左子树和右子树后,我们将它们连接到根节点上,就可以得到问题的答案。

这里我们用前序遍历和中序遍历去获得目标树,

前序遍历:[根节点|左子树|右子树]

中序遍历:[左子树|根节点|右子树]

根据前序遍历得到根节点,再在中序遍历中获得到左子树和右子树。

根节点在前序遍历中的索引子树在中序遍历的索引
当前树i[left , right]
左子树i + 1[left , mid - 1]
右子树i + 1 + (mid - left)[mid + 1 , right]

根据每次的索引,可以得到相对的根节点、左子树和右子树。

def dfs(preorder: list[int], inorder_map: dict[int, int], index: int, left: int, right: int):# 子树空了后终止if right - left < 0:return None# 初始化根节点root = TreeNode(preorder[i])# 查询mid,可以划分左右子树mid = inorder_map[preorder[index]]# 构建左子树root.left = dfs(preorder, inorder_map, index + 1, left, mid - 1)# 构建右子树root.right = def(preorder, inorder_map, index + 1 + mid - left, mid + 1, right)# 返回根节点return rootdef build_tree(preorder: list[int], inorder: list[int]):# 初始化哈希表inorder_map = {val: index for index, val in enumerate(inorder)}root = dfs(preorder, inorder_map, 0, 0, len(inorder) - 1)return root

相关文章:

  • Nest.js实现一个简单的聊天室
  • 24.9.27学习笔记
  • WebRTC关键技术及应用场景:EasyCVR视频汇聚平台高效低延迟视频监控解决方案
  • C++:模拟实现string
  • 如何使用 WebRTC 获取摄像头视频
  • 用Promise实现前端并发请求
  • 老古董Lisp实用主义入门教程(12):白日梦先生的白日梦
  • C++11标准模板(STL)- 常用数学函数 - 计算一个数的给定次幂 (xy)(std::pow, std::powf, std::powl)
  • Autosar EcuM学习笔记-上电初始化执行函数及下电前执行函数
  • 逆变器控制技术
  • 数据结构与算法——Java实现 24.中缀表达式转后缀
  • Python | 第八章 | 数据容器
  • 爬虫入门 Selenium使用
  • 906. 超级回文数
  • 算法复杂度-空间
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【Amaple教程】5. 插件
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 【技术性】Search知识
  • Angularjs之国际化
  • ECS应用管理最佳实践
  • emacs初体验
  • express.js的介绍及使用
  • Map集合、散列表、红黑树介绍
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • vue-cli3搭建项目
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 让你的分享飞起来——极光推出社会化分享组件
  • 入口文件开始,分析Vue源码实现
  • 删除表内多余的重复数据
  • 微信支付JSAPI,实测!终极方案
  • 我建了一个叫Hello World的项目
  • 怎么把视频里的音乐提取出来
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ‌JavaScript 数据类型转换
  • #{} 和 ${}区别
  • (vue)el-tabs选中最后一项后更新数据后无法展开
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (待修改)PyG安装步骤
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (算法)硬币问题
  • (小白学Java)Java简介和基本配置
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .Net Core中的内存缓存实现——Redis及MemoryCache(2个可选)方案的实现
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET简谈设计模式之(单件模式)
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • 。Net下Windows服务程序开发疑惑
  • @Resource和@Autowired的区别