背景

虽然平时工作涉及的主要内容是NLP相关,但是在处理数据,以及实现相关NLP的过程中难免不遇上一些基本算法的内容。分治就是一种比较好的算法思维,有必要对他进行深入了解和熟练使用。

算法内容

所谓分治算法就是采取分而治之的思想。在分析一些问题的时候可以从以下三个步骤考虑能否使用:

  1. Divid: 待解决的问题能否分割成多个相同的子问题
  2. Conquer:将子问题找到合适的解决方法
  3. Combine:将每个子问题的解决方法进行合并,形成主问题的最终解决方法

总结一下,这些问题的特征:子问题之间相互独立,子问题的解可以合并为原问题的解。例如在排序中,冒泡排序的时间复杂度O(n2)O(n^2)O(n2),使用分治方法可以将时间复杂度做到O(nlog⁡n)O(n\log n)O(nlogn)。

案例

归并排序(Merge Sort)案例

def merge_sort(data_list):"""归并排序:param data_list:  待排序数组:return: 排序后的结果"""if len(data_list) <= 1:return data_listdef merge(_left: list, _right: list):"""排序后的结果合并:param _left: 右边内容:param _right: 左边内容:return: 排序后的结果"""result = []head_l = head_r = 0while head_l < len(_left) and head_r < len(_right):if _left[head_l] < _right[head_r]:result.append(_left[head_l])head_l += 1else:result.append(_right[head_r])head_r += 1if head_l < len(_left):result.extend(_left[head_l:])else:result.extend(_right[head_r:])return resultmiddle = len(data_list) // 2left = merge_sort(data_list[: middle])right = merge_sort(data_list[middle: ])return merge(left, right)if __name__ == '__main__':result = merge_sort([0,3, 1, -1, 2, 4])print(result)  # [-1, 0, 1, 2, 3, 4]

对于归并排序的图解可参考:LeetCode上的介绍,感觉讲的挺好。时间复杂度方面:拆分的次数与下面二分查找一致为⌈log⁡2n⌉\lceil \log_2n \rceil⌈log2​n⌉,在合并的时候需要进行比较,最后的时间复杂度就是nlog⁡nn\log_nnlogn​.

二分查找(Binary Search)案例

def binary_search(data_list: list, target):"""二分查找(只返回列表中一个目标元素对应的索引):param data_list: 待查找的list,有序(升序、倒序皆可)的数字列表:param target: 目标值:return: 元素对应的索引,-1 表示没有找到"""start = 0end = len(data_list)while start <= end:mid = int(start + (end - start) / 2)  # 中间值索引mid_value = data_list[mid]if target == mid_value:return midelif mid_value > target:end = mid - 1else:start = mid + 1return -1if __name__ == '__main__':result = binary_search([-1, 0, 1, 2, 3, 4], 0)print(result)  # 1

其中数据查找的次数为⌈log⁡2n⌉\lceil \log_2n \rceil⌈log2​n⌉(向上取整的结果),对应的算法复杂度就是O(log⁡2n)O(\log_2n)O(log2​n)。如果数组是均匀分布的,还可以使用插值查找

如果想在具体的题目上练习,可以在LeetCode上尝试一下:二分查找题目。

快速排序(Quick Sort)案例

从数列中挑出一个元素,称为 “基准”(pivot);

重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

def quick_sort(data_list: list, left=None, right=None):left = 0 if not isinstance(left, (int, float)) else leftright = len(data_list) - 1 if not isinstance(right, (int, float)) else rightdef partition(arr, _left, _right):"""分区:param arr:  待分区数组:param _left: 起始index:param _right: 结束index:return: 基准index"""pivot = left  # 从最左边开始i = index = pivot + 1  # 最左边的下一个值开始比较while i <= _right:if arr[i] < arr[pivot]:  # 比基准小的值放到基准的左边(先放到连续的右边)arr[i], arr[index] = arr[index], arr[i]index += 1  # 记录基准小的值的边界i += 1# 基准与边界值交换完成基准值左边比基准值小,右边比基准值大arr[pivot], arr[index - 1] = arr[index - 1], arr[pivot]return index - 1  # 返回基准值索引if left < right:partition_index = partition(data_list, left, right)quick_sort(data_list, left, partition_index - 1)quick_sort(data_list, partition_index + 1, right)return data_list

对于快速排序的图解可参考LeetCode
原理可参考如下动画:

【算法与数据结构】分治(Divid Conquer)算法——以快排,归并排序,二分查找为例相关推荐

  1. C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划

    C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划 博文末尾支持二维码赞赏哦 _ github 章3 Stack栈 和 队列Queue= ...

  2. 【算法与数据结构专场】BitMap算法基本操作代码实现

    上篇我们讲了BitMap是如何对数据进行存储的,没看过的可以看一下[算法与数据结构专场]BitMap算法介绍 这篇我们来讲一下BitMap这个数据结构的代码实现. 回顾下数据的存储原理 一个二进制位对 ...

  3. 数据结构源码笔记(C语言):二分查找

    //实现二分查找的算法#include<stdio.h> #include<malloc.h> #include<malloc.h>#define MAXL 100 ...

  4. 【数据结构与算法】数据结构有哪些?算法有哪些?

    1. 算法与数据结构总览图 2.常用的数据结构 2.1.数组(Array) 数组是一种聚合数据类型,它是将具有相同类型的若干变量有序地组织在一起的集合.数组可以说是最基本的数据结构,在各种编程语言中都 ...

  5. 算法与数据结构模版(AcWing算法基础课笔记,持续更新中)

    AcWing算法基础课笔记 文章目录 AcWing算法基础课笔记 第一章 基础算法 1. 排序 快速排序: 归并排序: 2. 二分 整数二分 浮点数二分 3. 高精度 高精度加法 高精度减法 高精度乘 ...

  6. 02_Python算法+数据结构笔记-冒泡排序-选择排序-插入排序-快排-二叉树

    b站视频:路飞IT学城 清华计算机博士带你学习Python算法+数据结构_哔哩哔哩_bilibili 文章目录 #11 排序介绍 #12 冒泡排序介绍 #13 冒泡排序 #14 选择排序 #15 插入 ...

  7. python算法与数据结构:08排序算法

    稳定性定义:相同的值在排序结束之后的相对次序不变. 1. 冒泡排序 每一轮相邻两个值之间比较,大小顺序相反的交换位置,最后的值总是最大. 稳定性:稳定 def BubbleSort(alist):&q ...

  8. 走进算法和数据结构(二)——算法绪论(二)

    14天阅读挑战赛 上一节说到算法的基本概念,算法与数据结构的关系,那算法的好坏是怎么度量的呢?这一节我们就来探讨一下. 所谓一个好的算法,无非是执行效率高,所用时间短,当然这时间的快慢有时和计算机有一 ...

  9. 走进算法和数据结构(一)——算法绪论(一)

    14天阅读挑战赛 很偶然的机会,看到了CSDN举办14天阅读打卡活动,是关于算法的有关内容,正巧,自己也想写写算法.数据结构的知识,于是,借助这个机会,开始自己写算法和数据结构的专题内容. 算法和数据 ...

最新文章

  1. 基于python的分类预测_机器学习算法(五): 基于支持向量机的分类预测
  2. php 请求转发 重定向,PHP怎么实现页面重定向?(图文+视频)
  3. 小试牛刀chrome来调试APP
  4. loadrunner脚本设计:集合点(批量放行实现真正的并发)
  5. 39 岁网络技术员入住养老院,早 6 晚 9 的作息、和老人一起追剧晒太阳!
  6. 我要发明计算机作文,我想发明什么作文小学四年级
  7. 十八个超经典故事 绝对不会后悔
  8. mfc140dll 丢失 微软常用运行库_微软常用运行库合集 2020.9月(32amp;64位)
  9. HTML+CSS+JS实现 ❤️canvas圆形水波进度条动画特效❤️
  10. Python 装饰器@functools.wraps(func)
  11. 优化 Perl 榨取代码的最大性能
  12. python中pandas库里的read_table和read_csv的区别
  13. linux 查看添加的镜像源,linux镜像源的查看、配置以及删除
  14. Python数据分析师特训营84节
  15. 木头也要懂得讲故事的时代
  16. 计算机系新春祝福语,春节的祝福语
  17. Python爬虫实战:爬取拉勾网并对其进行数据分析
  18. 查看网站服务器版本,查看网站为TLS或SSL及其版本
  19. ICC小Tips集锦
  20. 各大搜索引擎网站登录入口大全

热门文章

  1. “有点笨”的数学大师迈克尔·弗里德曼
  2. Date DateFormat SimpleDateFormat Calendar Joda-Time
  3. python统计列分布_pd.DataFrame统计各列数值多少的实例
  4. Linux的命令回收站在哪,Trash-Cli:Linux 上的命令行回收站工具
  5. 重庆千年古镇摆千米长宴迎新年
  6. 怎样在计算机查找应用程序,电脑打开IE浏览器显示找不到应用程序怎么解决
  7. html跳转到关注的微信公众号,手机浏览器一键跳转微信公众号关注的方法
  8. Word中怎么打分段函数?
  9. 太酷了!金山云重磅开源鎏光云游戏引擎
  10. 全球AI技术开放日系列5(上海站):走进爱奇艺