Encuentre el K-ésimo número más pequeño (más grande) en una matriz desordenada, utilizando el método del problema de la bandera holandesa para resolver
la complejidad del tiempo (valor esperado): O (N)
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
void swap(vector<int>& arr, int n1, int n2) {
int tmp = arr.at(n1);
arr.at(n1) = arr.at(n2);
arr.at(n2) = tmp;
}
vector<int> partition(vector<int>& arr, int left, int right) {
// 随机选择一个值作为划分值
int index = left + (rand() % (right - left + 1));
// 将选择的随机值置换到末尾
swap(arr, index, right);
int tmpL = left - 1;
int tmpR = right;
index = left;
while (index < tmpR) {
if (arr.at(index) < arr.at(right)) {
swap(arr, index++, ++tmpL);
}
else if (arr.at(index) > arr.at(right)) {
swap(arr, index, --tmpR);
}
else {
index++;
}
}
swap(arr, index, right);
vector<int> res{
tmpL, tmpR + 1 };
return res;
}
// 时间复杂度: O(N)
// 最差情况每次只排好一个数O(N^2); 最好情况T(N)=T(N/2)+O(N)=O(N); 期望值O(N)
int getMinKth(vector<int>& arr, int k, int left, int right) {
if (arr.empty() || arr.size() < k || k < left || k > right || right < left) {
return -1;
}
// 进行划分: < 左,= 中,> 右
vector<int> range = partition(arr, left, right);
// 若K恰好在 等于区域 直接返回
if (k > range.at(0) && k < range.at(1)) {
return arr.at(k);
}
// 否则,如果k在 小于区域 小于区域继续递归,如果k在 大于区域 大于区域继续递归
return k <= range.at(0) ? getMinKth(arr, k, left, range.at(0)) : getMinKth(arr, k, range.at(1), right);
}
int main() {
srand(time(0));
vector<int> arr{
10, 4, 2, 9, 0, 12, 10, 22 };
cout << getMinKth(arr, 6, 0, arr.size() - 1) << endl;
system("pause");
return 0;
}
Si hay alguna infracción, comuníquese para eliminarla. Si hay un error, corríjame, gracias