在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
思路
这题方法有很多
第一种:直接sort(v.begin(),v.end()) 时间复杂度是nlog(n)
第二种:使用堆排序 由于题目需要求第k大,因此我们建立小根堆,最后的堆顶就是第k大,时间复杂度是nlog(k)
第三种方法 我们采用二分的思想并且结合快排。快排的性质是每次都可以将一个数放在最终位置上面,并且左边比此数小,右边比此数大。
快排代码如下:
#include <iostream>
#include<vector>
#include <ctime>
#include<algorithm>
using namespace std;
void quicksort(vector<int> &arr,int left,int right)
{
int i, j, t, temp;
if (left > right)
return;
temp = arr[left];
i = left;
j = right;
while (i != j)
{
while (arr[j] >= temp && i < j)
j--;
while (arr[i] <= temp && i < j)
i++;
if (i < j)
{
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
//交换哨兵和确认所在位置i的数据
arr[left] = arr[i];
arr[i] = temp;
cout << "已确认交换位置 i=" << i << endl;
quicksort(arr,left,i-1);
quicksort(arr, i +1,right);
}
二分法代码:
#include<iostream>
using namespace std;
int binarySearch(int *arr, int low, int high, int target)//递归实现
{
int middle = (low + high) / 2;
if (low > high)
return -1;
if (arr[middle] == target)
return middle;
if (arr[middle] > target)
return binarySearch(arr, low, middle - 1, target);
if (arr[middle] < target)
return binarySearch(arr, middle + 1, high, target);
};
int binarySearch1(int nums[], int n, int target)//循环实现
{
if (n == 0)
{
return -1;
}
int hight = n - 1;
int low = 0;
int middle;
while (low <= hight)
{
middle = (low + hight) / 2;
if (nums[middle] > target)
{
hight = middle - 1;
}
else if (nums[middle] < target)
{
low = middle + 1;
}
else if (nums[middle] == target)
{
return middle;
}
}
return -1;
};
int main()
{
int a[10] = { 5,6,7,8,9, 10 , 11, 12 ,13, 14 };
int index = binarySearch(a, 0, 9, 12);
cout << index << endl;
int index2 = binarySearch1(a, 10, 12);
cout << index2 << endl;
system("pause");
}
此题使用二分法结合快排思想代码如下
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int low = 0;
int high = nums.size() - 1;
int seg = -1;
while (seg!=nums.size() - k) {
seg = partition(nums, low, high);
if (seg == nums.size() - k) //第k大 就是 第nums.size()-k小
{
cout<<"seg="<<seg;
break;
}
else if (seg > nums.size() - k)
high = seg - 1;
else
low = seg + 1;
}
return nums[seg];
}
int partition(vector<int>& nums, int low, int high) {
int i = low;
int j = high;
int key = nums[low];
while (i != j) {
while (nums[j] >= key && i < j)
j--;
while (nums[i] <= key && i < j)
i++;
if (i < j)
swap(nums[i], nums[j]);
}
swap(nums[i], nums[low]); //注意这里swap按引用换值
return i;
}
};