📅  最后修改于: 2023-12-03 15:37:43.136000             🧑  作者: Mango
在处理数组相关问题时,查找数组中第 k 个最大或最小元素是一种常见的需求。本文介绍如何使用 C++ 实现这种问题。
数组中第 k 个最大或最小元素可以通过排序来解决。排序后,第 k 个元素即为所需元素。时间复杂度为 O(nlogn)。
以下是 C++ 实现:
// 查找第 k 个最大元素
int findKthLargest(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
return nums[nums.size() - k];
}
// 查找第 k 个最小元素
int findKthSmallest(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
return nums[k - 1];
}
使用堆来查找第 k 个最大或最小元素可以将时间复杂度优化到 O(nlogk)。
以下是 C++ 实现:
// 查找第 k 个最大元素
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> minHeap; // 小根堆
for (int num : nums) {
minHeap.push(num);
if (minHeap.size() > k) {
minHeap.pop();
}
}
return minHeap.top();
}
// 查找第 k 个最小元素
int findKthSmallest(vector<int>& nums, int k) {
priority_queue<int> maxHeap; // 大根堆
for (int num : nums) {
maxHeap.push(num);
if (maxHeap.size() > nums.size() - k + 1) {
maxHeap.pop();
}
}
return maxHeap.top();
}
快速选择是基于快速排序算法的一种改进。在快速排序中,每次递归时需要同时对左右子数组递归。而在快速选择中,仅需要递归一边即可,这样可以将时间复杂度优化到 O(n)。
以下是 C++ 实现:
int quickSelect(vector<int>& nums, int l, int r, int k) {
if (l == r) {
return nums[l];
}
int pivotIndex = l + rand() % (r - l + 1);
int pivot = nums[pivotIndex];
int left = l, right = r;
swap(nums[l], nums[pivotIndex]);
while (left < right) {
while (left < right && nums[right] >= pivot) {
right--;
}
nums[left] = nums[right];
while (left < right && nums[left] < pivot) {
left++;
}
nums[right] = nums[left];
}
nums[left] = pivot;
int lessCount = left - l + 1;
if (lessCount == k) {
return nums[left];
} else if (lessCount > k) {
return quickSelect(nums, l, left - 1, k);
} else {
return quickSelect(nums, left + 1, r, k - lessCount);
}
}
// 查找第 k 个最大元素
int findKthLargest(vector<int>& nums, int k) {
return quickSelect(nums, 0, nums.size() - 1, nums.size() - k + 1);
}
// 查找第 k 个最小元素
int findKthSmallest(vector<int>& nums, int k) {
return quickSelect(nums, 0, nums.size() - 1, k);
}
总结:
因此,针对不同的数据规模和数据特征,选择不同的算法来解决问题。