排序算法

  在算法设计中,我们通常会使用到以下这些排序算法:

  1. O(n2)算法:选择排序,插入排序,冒泡排序
  2. O(nlogn)算法:堆排序,快速排序,归并排序
  3. 下界为O(nlogn)算法:基数排序,计数排序,桶排序

  其中,第二类算法的时间复杂度是最低的,而第三类算法是换了一种思路的排序方式。它们不是按数的大小来比较,而是利用数位划分,和数字间的映射关系而进行排序的,这些排序算法的时间复杂度不仅仅跟数字的个数n有关,也和数据的范围有关。

离散化

  离散化就是把一些分布密度较小,且进行的变化和数的绝对大小无关(只把这些数作为i代表或只与这些数的相对顺序有关)。此时,我们只用把这些m个数与1~m建立起映射关系。从而缩小整个问题的空间。

  具体地说,假设为int范围内的n个整数,在去重后有m个,对于这其中的每一个数a[i]我们都能够找到1~m之间的数与之形成映射关系,最后的查找只需要二分即可。

void discrete() // 离散化 
{
    sort(a + 1, a + n+1);
    for(int i = 1; i <= n; ++ i)  // 去重 
        if(i == 1 || a[i] != a[i - 1])
            b[++ m] = a[i];
 } 
 
 void query(int x) // 查询 x 映射为了 1 ~ m 内的哪个数 
 {
     return lower_bound(b + 1, b + m + 1, x) - b;
  } 

中位数

  在有序序列中,中位数具有一些很Prefect的性质,可以引出一系列与他相关的问题(实际上是一个贪心策略)。

【例题1】货仓选址

  在一条数轴上有N家店,他们的坐标分别为A[1] ~ A[n]。现在徐娅在数轴上建立一家仓库,每天清晨,从货仓到每家商店的都要运送一车商品。为了提高效率,求把仓库建在何处,可以保证距离之和最小。

  我们可以很轻松地得到最优解为最中间一个和最中间的两个之间的任意一点,而我们把问题给抽象化即为求一个k使得式子成立,而这个k的取值就为

【例题2】待更新……

第k大的数

  给定n个整数,如何求第k大的数?我们可以直接对这n个整数进行快速排序,然后输出从小到大的第k大的数,在快排过程中,我们可以进行如下的优化:

  从大到小进行快排的思想中,每一层的递归中,我们都要选取一个数作为基准,把比他大的数放在左边,比他小的数放在右边。而在每次选出基准数之后,我们可以统计出大于大于基准数的数量cnt,如果k<=cnt,我们就在左半段找第k大的数;如果k>cnt。我们就在有半段找第(cnt-k)个数。

 逆序数对

  待更新……

原文地址:https://www.cnblogs.com/2020pengxiyue/p/9404551.html