卜算法学习笔记-02-分而治之算法02

数组中的逆序对计数

算法分析

所谓逆序对,是指数组中的两个元素 A [ i ] A[i] A[i] A [ j ] A[j] A[j],其下标 i < j i < j i<j,但是考察元素的值,却有 A [ i ] > A [ j ] A[i] > A[j] A[i]>A[j]
输入:一个包含 n n n 个元素的数组 A [ 0.. n − 1 ] A[0..n − 1] A[0..n1];
输出:数组中的逆序对的数目。
从最简单的实例入手:如果数组 A 只有两个元素 A[0] 和 A[1],我们只需比较这两个元素,即可计算出逆序数。
接下来我们考虑如何求解规模更大的实例。对于一个包含 n n n 个元素的数组 A,我们可以很容易地依据下标将 A 分解成两个小的数组,即左一半 A [ 0.. ⌈ n 2 ⌉ − 1 ] A[0..⌈ \frac{n}{2} ⌉ − 1] A[0..2n1](简记为 L L L)和右一半 A [ ⌈ n 2 ⌉ . . n − 1 ] A[⌈ \frac{n}{2} ⌉..n − 1] A[⌈2n..n1](简记为 R R R)。在将大的实例分解成子实例之后,我们可以假定子实例已经求解,即使用递归调用分别求出两个元素都在 L L L 中的逆序对数目、 以及两个元素都在 R R R 中的逆序对数目;因此只剩下最后一个困难:如何将子实例的 解“组合”成原始给定实例的解。
逆序对计数算法中计算一个元素在右半边,一个元素在右半边的逆序对数目:如果 L L L R R R 都已经排好序的话,只需执行 O ( n ) O(n) O(n) 次比较即可完成逆序对的计数。
逆序对计数算法伪代码

时间复杂度

T ( n ) = 2 T ( n 2 ) + O ( n ) = O ( n log ⁡ n ) T(n) = 2T(\frac{n}{2}) + O(n) = O(n \log n) T(n)=2T(2n)+O(n)=O(nlogn)

选择问题:对数组的归约

如何从数组中找出第 k 小的数
输入:一个包含 n n n 个元素的数组 A [ 0.. n − 1 ] A[0..n − 1] A[0..n1],以及一个整数 k , ( 0 ≤ k ≤ n − 1 ) k,(0 ≤ k ≤ n − 1) k(0kn1);
输出:数组 A A A 中第 k k k 小的元素。
采用依据元素值拆分数组的方案:
选择问题的通用框架

选择分组中位数的中位数作为中心元

算法分析

方法:将数组 A A A分组,然后以组中位数作为 A A A的近似,进而以组中位数的中位数作为中心元
可以看到,组中位数的中位数在该数前面和后面均有一定量的值大于和小于他们(可以计算,如分组数为 m m m,每组有 n n n个数,为了方便计算,假设 m 、 n m、n mn都是奇数,那么比该数小的数至少有 ⌈ n 2 ⌉ × ⌈ m 2 ⌉ − 1 \lceil \frac{n}{2} \rceil \times \lceil \frac{m}{2} \rceil - 1 2n×2m1,比组中位数的中位数大的数也有 ⌈ n 2 ⌉ × ⌈ m 2 ⌉ − 1 \lceil \frac{n}{2} \rceil \times \lceil \frac{m}{2} \rceil - 1 2n×2m1个)
求解选择问题的BFPRT算法

时间复杂度分析

算法总共需要比较的次数不超过 24 n 24n 24n
T ( ) ≤ T ( n 5 ) + T ( 7 n 10 ) + O ( n ) = O ( n ) T() \leq T(\frac{n}{5}) + T(\frac{7n}{10}) + O(n) = O(n) T()T(5n)+T(107n)+O(n)=O(n)

依据随机样本的统计量确定中间元

算法分析

构造数组的近似,一个直观的想法是对数组进行随机采样,以随机采样来近似数组,进而利用样本的统计量来确定中心元,比如采用样本中位数作为中心元,还进行一个扩展,不是只使用样本的中位数,而是使用 1 4 分位数和 \frac{1}{4}分位数和 41分位数和 3 4 \frac{3}{4} 43分位数,将点估计扩展成区间估计。
假设随机采样的数量为 r r r,采样 r r r的元素得到的样本为 S S S,之后计算出 S S S的分位数 u u u v v v,接着对每个元素都和 u u u v v v比较,依据比较结果分别放入集合 L , M , H L,M,H L,M,H,最后将 M M M排序,返回其中位数作为数组的中位数估计:
依据随机样本的统计量确定中间元的方法

时间复杂度分析

对于一个包含 n n n个元素的数组 A A A,当设置 r = n 3 4 , δ = n − 1 4 r = n^{\frac{3}{4}},\delta = n^{-\frac{1}{4}} r=n43,δ=n41,算法的期望时间复杂度是 O ( n ) O(n) O(n),此时位于 u , v u,v u,v区间的 S S S中的元素共有 n − 1 4 × r n^{-\frac{1}{4}} \times r n41×r个,所以可以期望位于 u , v u,v u,v区间的 A A A中的元素共有 n − 1 4 × n = n 3 4 n^{-\frac{1}{4}} \times n = n^{\frac{3}{4}} n41×n=n43个,所以 ∣ ∣ M ∣ ∣ ||M|| ∣∣M∣∣不会太大也不会太小

采用随机选择的一个元素作中心元

算法分析

我们有 1 2 \frac{1}{2} 21的概率选到中间区域的元素,所以连续迭代两轮,可以以很高的概率使得子问题的规模呈指数级降低
随机选择中心元

时间复杂度分析

可以看到将每两次算法执行作为一期
T ( n ) = T ( 3 n 4 ) + 2 n = O ( n ) T(n) = T(\frac{3n}{4}) + 2n = O(n) T(n)=T(43n)+2n=O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值