分治法——线性时间选择

简介: 分治法——线性时间选择

算法思想:利用快速排序的方法将a[p:r]被划分成两个子数组a[p:i]和a[i+1:r],使a[p:i]中的每个元素都不大于a[i+1:r]中每个元素。接着算法计算子数组a[p:i]中元素个数j。如果k≤j,则第k小的数落在左区间,否则落在右区间,直到k=j时,找到第k小的数。


对于有重复数字的无法解决。其实维护小顶堆感觉更好,无论时间复杂度还是代码复杂程度。

int Partiotion(int a[], int p, int r) {
  int i = p;
  int j = r + 1;
  int x = a[p];//划分的基准
  while (true) {
    while (a[++i] < x && i < r);//找到第一个比基准大的元素
    while (a[--j] > x);//找到比基准大的元素
    if (i >= j) {
      break;
    }
    swap(a[i], a[j]);//交换两个位置不正确的元素
  }
  a[p] = a[j];
  a[j] = x;
  return j;
}
int RandomizedPartition(int a[], int p, int r) {//随机选择基准优化快速排序,区间对称性
  int i = rand() % (p - r + 1) + p;
  swap(a[i], a[p]);
  return Partiotion(a, p, r);
}
int RandomizedSelect(int a[], int low, int high, int k) {
  if (low == high) {
    return a[low];
  }
  int i = Partiotion(a, low, high);
  int j = i - low + 1;
  if (k <= j) {
    return RandomizedSelect(a, low, i, k);
  }
  else {
    return RandomizedSelect(a, low+1, high, k-j);
  }
}
相关文章
|
5月前
|
算法 Java 程序员
认识复杂度、对数器、二分法
认识复杂度、对数器、二分法
55 1
|
5月前
|
算法 测试技术 C++
【动态规划】【图论】【C++算法】1928规定时间内到达终点的最小花费
【动态规划】【图论】【C++算法】1928规定时间内到达终点的最小花费
|
5天前
|
搜索推荐 算法
插入排序算法的平均时间复杂度解析
【10月更文挑战第12天】 插入排序是一种简单直观的排序算法,通过不断将未排序元素插入到已排序部分的合适位置来完成排序。其平均时间复杂度为$O(n^2)$,适用于小规模或部分有序的数据。尽管效率不高,但在特定场景下仍具优势。
动态规划|【斐波那契数列模型 】|746.使用最小花费爬楼梯
动态规划|【斐波那契数列模型 】|746.使用最小花费爬楼梯
|
5月前
|
算法 C++ 索引
寻找最接近子数组和的算法设计及其C++实现
寻找最接近子数组和的算法设计及其C++实现
39 4
|
5月前
|
算法 Java C++
非启发式算法——二分、三分搜索算法
非启发式算法——二分、三分搜索算法
201 0
|
Java
简单计算时间复杂度
简单计算时间复杂度
32 1
|
搜索推荐 算法
认识复杂度和简单排序算法
认识复杂度和简单排序算法
76 0
算法的时间复杂度比较,计算多项式的直接法和秦九韶法
算法的时间复杂度比较,计算多项式的直接法和秦九韶法
算法的时间复杂度比较,计算多项式的直接法和秦九韶法