我的解法:暴力查表
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
multimap<int,int> contact;
int i=-1;
for(auto a:nums){
contact.insert({a,++i});
}
int size=contact.size();
vector<int> rank;
auto it=contact.cbegin();
for(i=0;i<size;i++){
rank.push_back(it->first);
it++;
}
return rank[size-k];
}
};
官方解法:
快速查找:
根据官方java写出的C++
class Solution {
vector<int> num;
//重载swap
void swap(int a,int b){
int tmp=num[a];
num[a]=num[b];
num[b]=tmp;
}
//得出轴心值位置(大于左边,小于右边)
int partition(int left,int right,int pivot_index){
int pivot=num[pivot_index];//获取轴心值
swap(pivot_index,right);//将轴心值放到最右端
int store_index=left;//由最左端开始遍历,相当于指针
for(int i=left;i<=right;i++){
if(num[i]<pivot){//当前值与轴心值进行比较
swap(store_index,i);//小于就交换到左边
store_index++;//交换就增加位置指针
}//大于就保持位置,等出现小值后交换走
}
//把轴心值交换到应处位置(大于左边,小于右边)
swap(store_index,right);
//返回位置
return store_index;
}
int quickseclect(int left,int right,int k_smallest){
//递归出口
if(left==right){
return num[left];
}
int pivot_index= left + rand()%(right - left);//生成随机值:left+[0,right-left)
pivot_index = partition(left, right, pivot_index);//获取轴心值位置
if (k_smallest==pivot_index){//根据结果更改遍历范围
return num[k_smallest];
}else if (k_smallest<pivot_index){
return quickseclect(left, pivot_index-1, k_smallest);
}else {
return quickseclect(pivot_index+1, right, k_smallest);
}
}
public:
int findKthLargest(vector<int>& nums, int k) {
num=nums;//传递数组
int size=nums.size();
return quickseclect(0,size-1,size-k);//找出第k大
}
};
参考1738题写法:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//nth_element(首,定位位置:所用规则第K个,尾,规则:此处为升序)->定位到第K大
nth_element(nums.begin(), nums.begin() + k - 1, nums.end(), greater<int>());
return nums[k-1];
}
};
STL之nth_element详解 - 百度文库https://wenku.baidu.com/view/09ba240eccc789eb172ded630b1c59eef8c79a8e.html
例如挖坑法等:
class Solution
{
public:
int findKthLargest(vector<int>& nums, int k)
{
int n = nums.size();
int l = 0;
int r = n - 1;
while (true)
{
int idx = partition(nums, l, r);
if (idx == k - 1)//更换遍历区间
return nums[idx];
else if (idx < k - 1)
l = idx + 1;
else
r = idx - 1;
}
}
//----左右挖坑互填
int partition(vector<int> & nums, int l, int r)
{
int pivot = nums[l];
while (l < r)
{
while (l < r && nums[r] <= pivot)//较大的值被放到左边
r --;
nums[l] = nums[r];
while (l < r && nums[l] >= pivot)//较小的值放到右边
l ++;
nums[r] = nums[l];
}
nums[l] = pivot;//将轴心值放回坑中方便下一轮递归
return l;//返回轴心值位置
}
};
基本思路:
定义两个指针left指向起始位置,right指向最后一个元素的位置,然后指定一个基数key(right),作为坑
left寻找比基数(key)大的数字,找到后将left的数据赋给right,left成为一个坑,然后right寻找比基数(key)小的数字,找到将right的数据赋给left,right成为一个新坑,循环这个过程,直到begin指针与end指针相遇,然后将key返回给那个坑(最终:key的左边都是比key小的数,key的右边都是比key大的数),然后进行递归操作。
快速排序一些方法思路: