详解CDQ算法
在这篇文章中, 我将带大家走进CDQ算法。
什么是CDQ算法
从二分说起
在解释cdq算法之前, 首先回顾算法中非常经典的分而治之。
Divide And Conquer(分而治之)
分而治之是计算机科学中非常经典的思想, 通常会把一个比较复杂的大问题, 分成两个(或多个)子问题, 分别递归分而治之去解决这些子问题, 最后把子问题的结果合并为原问题的解。
有了以上分而治之的思想后, 我们可以看一个非常经典的算法例子归并排序。
归并排序:
归并排序有以下几个步骤
- 把数组分成做左区间和右区间
- 分别对左区间和右区间进行归并排序
- 把左区间和右区间的排好序的数组合并成一个有序的数组
归并排序的复杂度是O(nlogn)
代码如下
void merge(vector<int> &arr, vector<int> &tmp, int l, int m, int r) {
int i = l, j = m + 1, p = 0;
while (i <= m && j <= r) {
if (arr[i] < arr[j])
tmp[p++] = arr[i++];
else
tmp[p++] = arr[j++];
}
while (i <= m)
tmp[p++] = arr[i++];
while (j <= r)
tmp[p++] = arr[j++];
for (i = 0, j = l; i < p; )
arr[j++] = tmp[i++];
}
void mergeSort(vector<int> &arr, vector<int> &tmp, int l, int r) {
if (r > l) {
int