1. 题目解析
题目链接:数组中的第K个最大元素
这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。
2.算法原理
在快速排序算法中,一种常见的优化策略是将数组划分为三个区间。这种划分方式可以更加精确地定位到目标元素所在的位置,从而加快排序速度。具体地,这三个区间为:[l, left]、[left + 1, right - 1] 和 [right, r]。
-
区间划分:
- 首先,选定一个基准元素(pivot),通常选择数组的第一个元素或最后一个元素。
- 然后,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小。
- 这个分割过程结束后,基准元素所处的位置就是数组的一个划分点,该点将数组分成左右两个子区间。
-
计算区间元素个数:
- 在完成划分后,我们计算每个区间的元素个数。这可以通过遍历每个区间并计数来实现。
- 特别地,对于中间区间 [left + 1, right - 1],它包含了所有与基准元素相等的元素。
-
推断目标元素位置:
- 有了每个区间的元素个数,我们就可以推断出目标元素可能位于哪个区间。
- 如果目标元素小于基准元素,则它必定位于左区间 [l, left] 中;如果目标元素大于基准元素,则它位于右区间 [right, r] 中;如果目标元素等于基准元素,则它可能位于中间区间 [left + 1, right - 1] 中。
-
定位并返回结果:
- 根据推断出的目标元素所在区间,我们直接在该区间内进行搜索或返回结果。
- 如果目标元素存在于中间区间,并且我们关心的是第一个或最后一个等于基准元素的元素,我们可以直接返回该区间的起始或结束位置。
3.代码编写
class Solution
{
public:
int findKthLargest(vector<int>& nums, int k)
{
srand(time(nullptr));
return qsort(nums, 0, nums.size() - 1, k);
}
int qsort(vector<int>& nums, int l, int r, int k)
{
if(l == r) return nums[l];
//1.随机算则一个基准元素
int key = getRandom(nums, l, r);
//2.将数组分三块
int left = l - 1, right = r + 1, i = l;
while(i < right)
{
if(nums[i] < key) swap(nums[++left], nums[i++]);
else if(nums[i] == key) i++;
else swap(nums[--right], nums[i]);
}
//3.分情况讨论
int c = r - right + 1, b = right - left - 1;
if(c >= k)
{
return qsort(nums, right, r, k);
}
else if(b + c >= k)
{
return key;
}
else
{
return qsort(nums, l, left, k -b -c);
}
}
int getRandom(vector<int>& nums, int l, int r)
{
return nums[rand() % (r - l + 1) + l];
}
};
The Last
嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。
觉得有点收获的话,不妨给我点个赞吧!
如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~