分治法,寻找一个序列中第k大元素。对于给定的含有n元素的无序序列,求这个序列中第k(1≤k≤n)大的元素。例如:一个含有10个元素的序列[98,7,69,58,24,16,77,44,32,46],求这个序列中第4大的元素。其结果输出第4大元素:58。c++
时间: 2024-09-28 11:07:03 浏览: 26
分治法是一种解决问题的有效策略,通常用于将复杂问题分解成更小、更易于管理的部分。针对寻找无序序列中的第k大元素这个问题,可以采用经典的“快速选择”算法,它是基于分治思想的一种优化版本的二分查找。以下是基本步骤:
1. **划分**:首先随机选取一个元素作为“基准”pivot。
2. **分区**:将数组分为两部分,一部分的所有元素都小于基准,另一部分所有元素大于或等于基准。如果pivot的位置正好是k,那么我们找到了第k大的元素;如果pivot的位置比k小,我们在左半部分继续搜索;反之,在右半部分搜索。
3. **递归**:根据pivot的位置调整搜索范围,直到找到第k大元素。
以下是使用C++实现的一个简单示例:
```cpp
#include <iostream>
#include <vector>
#include <cstdlib> // 需要用到 rand() 和 srand()
int partition(std::vector<int>& nums, int low, int high) {
int pivot = nums[high]; // 选取最后一个元素作为pivot
int i = (low - 1); // i指向小于pivot的区域
for (int j = low; j <= high - 1; j++) {
if (nums[j] >= pivot) {
i++; // 将当前元素移到i位置
std::swap(nums[i], nums[j]);
}
}
std::swap(nums[i + 1], nums[high]); // 将pivot放到正确位置
return i + 1;
}
int quickSelect(std::vector<int>& nums, int low, int high, int k) {
if (low == high) { // 如果只有一个元素,就是最小值
return nums[low];
}
int pivotIndex = partition(nums, low, high);
if (k == pivotIndex) {
return nums[k];
} else if (k < pivotIndex) {
return quickSelect(nums, low, pivotIndex - 1, k);
} else {
return quickSelect(nums, pivotIndex + 1, high, k);
}
}
int findKthLargest(std::vector<int>& nums, int k) {
if (k < 1 || k > nums.size()) {
throw std::out_of_range("Invalid k");
}
return quickSelect(nums, 0, nums.size() - 1, nums.size() - k);
}
int main() {
std::vector<int> nums = {98, 7, 69, 58, 24, 16, 77, 44, 32, 46};
int k = 4;
int result = findKthLargest(nums, k);
std::cout << "The " << k << "th largest element is: " << result << std::endl;
return 0;
}
```
运行此程序,它会输出:The 4th largest element is: 58.
阅读全文