Divide & Conquer Algorithms
O(n log n) Algorithm for Counting Inversions
- 分治算法
- 将问题分割为更小的子问题
- 通过递归调用解决这些问题
- 将子问题的结果合并到更大的子问题中作为其结果
- 逆序对
- 数组中存在的
i < j但是a[i] > a[j]的情况 - 左逆序对:二者都在左半部分
- 右逆序对:二者都在右半部分
- 跨逆序对:分别在两侧
- 数组中存在的
- 思路:将归并排序融合进来
- 两个半部分一边数逆序对一边排序,对两个有序的半部分再归并同时计算逆序对
- 归并时,对于右侧的一个数字y,若复制到目标数组时,其相关的逆序对个数即此时左侧剩下的元素个数
- 因为整个过程基于归并排序,因此与归并排序有着相同的时间复杂度(O(nlogn)O(n \log n)O(nlogn))
Strassen’s Subcubic Matrix Multiplication
- 直接计算矩阵:立方级别时间复杂度
- 递归算法:
- 将矩阵等分成四个部分
- 将两个矩阵的乘积转化为八个小矩阵的乘积(八个递归项)
- 做加和处理
- 仍旧是立方复杂度
- Steassen算法
- 递归项只有7个
- 进行必要的加和和相减处理
- 八个小矩阵为A~H
- 递归计算七个积:
- P1=A(F−H)P_1=A(F-H)P1=A(F−H)
- P2=(A+B)HP_2=(A+B)HP2=(A+B)H
- P3=(C+D)EP_3=(C+D)EP3=(C+D)E
- P4=D(G−E)P_4=D(G-E)P4=D(G−E)
- P5=(A+D)(E+H)P_5=(A+D)(E+H)P5=(A+D)(E+H)
- P6=(B−D)(G+H)P_6=(B-D)(G+H)P6=(B−D)(G+H)
- P7=(A−C)(E+F)P_7=(A-C)(E+F)P7=(A−C)(E+F)
- X+Y=(AE+BGAF+BHCE+DGCF+DH)=(P5+P4−P2+P6P1+P2P3+P4P1+P5−P3−P7)X+Y = (\begin{matrix}AE+BG & AF+BH \\ CE+DG & CF+DH\end{matrix}) = (\begin{matrix} P_5+P_4-P_2+P_6 & P_1+P_2 \\ P_3+P_4 & P_1+P_5-P_3-P_7 \end{matrix})X+Y=(AE+BGCE+DGAF+BHCF+DH)=(P5+P4−P2+P6P3+P4P1+P2P1+P5−P3−P7)
- 有效地降低了复杂度(次立方级别复杂度)
Closet Pair
- 最近点对问题:
- 给出一组平面上的点
- 找出其中距离最近的一对
- 距离为点的欧氏距离
- 假设所有点坐标不同(相同亦可)
- 暴力搜索:θ(n2)\theta(n^2)θ(n2)的时间复杂度
- 1-D平面上的点:归并排序后遍历相邻点的距离(O(nlogn)O(n \log n)O(nlogn))
- 基本思路:类似逆序对算法,进行归并式的寻找,时间复杂度同样为(O(nlogn)O(n \log n)O(nlogn))
- 关键思路:只计算尚未“解锁”的情形中距离比现有递归结果最小的部分
- 计算过程
- 将点按照坐标的从大到小排序,将Q和R表示为点集的左半部分和右半部分
- 计算(p1,q1)为Q中最近对
- 计算(p2,q2)为P中最近对
- 计算两个对的最小者的距离δ
- 根据δ和P,计算跨两部分的最近对(p3,q3)
- 取三者最小向上递归结果
- split最近对的寻找:线性时间扫描
- 一次只看7个点(已经按照y坐标排序)
The Master Method
- 对分治算法的数学分析:循环表示法(Recurrence)
- 循环表示法的形式化表示(假设子问题的大小均一致):
- 基本情形:对足够小的nnn,T(n)≤a constantT(n) \le \text{a constant}T(n)≤a constant
- 对其他更大的nnn:T(n)≤aT(nb)+O(nd)T(n) \le aT(\frac nb) + O(n^d)T(n)≤aT(bn)+O(nd)
- a:递归调用的个数
- b:输入大小的缩减因子
- d:对递归调用结果的加和操作的指数因子
- 如果a=bda=b^da=bd:T(n)=(ndlogn)T(n)=(n^d \log n)T(n)=(ndlogn)
- 如果a<bda < b^da<bd:T(n)=(nd)T(n)=(n^d)T(n)=(nd)
- 如果a>bda > b^da>bd:T(n)=(nlogba)T(n)=(n^{\log_b a})T(n)=(nlogba)
本文深入探讨了分治算法的基本原理及其在计数逆序对、Strassen矩阵乘法及最近点对问题中的应用。通过将问题分解为子问题,递归解决并合并结果,分治算法能有效降低复杂度,如O(nlogn)的逆序对算法和次立方级别的Strassen矩阵乘法。文章还介绍了主定理,用于分析分治算法的时间复杂度。
1531





