力扣链接
题目描述
给定整数数组 nums
和整数 k
,请返回数组中第 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
提示:
1 <= k <= nums.length <= 104
-104 <= nums[i] <= 104
解题思路
- api
- 快速选择
- 堆排序
代码(调api)
class Solution {
public int findKthLargest(int[] nums, int k) {
Arrays.sort(nums);
return nums[nums.length - k];
}
}
复杂度
- 时间复杂度: O(nlog(n))
- 空间复杂度: O(1)
代码(快速选择算法)
class Solution {
public int findKthLargest(int[] nums, int k) {
return quickSelect(nums, 0, nums.length - 1, k);
}
int quickSelect(int[] nums, int l, int r, int k) {
if (l == r) {
return nums[l];
}
int i = l;
int j = r;
int mid = i + j >> 1;
int pivot = nums[mid];
while (i <= j) {
while (i <= j && nums[i] > pivot) {
i++;
}
while (i <= j && nums[j] < pivot) {
j--;
}
if (i <= j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
j--;
}
}
if (l + k - 1 <= j) {
return quickSelect(nums, l, j, k);
}
if (l + k - 1 >= i) {
return quickSelect(nums, i, r, k - i + l);
}
return nums[j + 1];
}
}
复杂度
代码(堆排序)
class Solution {
//基于堆排序的选择方法
public int findKthLargest(int[] nums, int k) {
sort(nums, nums.length, k);
return nums[0];
}
static void sort(int[] nums, int heapSize, int k) {
buildMaxHeap(nums, heapSize);
while (heapSize > nums.length - k + 1) {
swap(nums, 0, --heapSize);
maxHeapify(nums, 0, heapSize);
}
}
static void buildMaxHeap(int[] nums, int heapSize) {
for (int i = (heapSize >> 1) - 1; i >= 0; i--) {
maxHeapify(nums, i, heapSize);
}
}
static void maxHeapify(int[] nums, int i, int heapSize) {
int a = 2 * i + 1;
int b = 2 * i + 2;
int max = i;
int len = nums.length;
if (a < heapSize && nums[max] < nums[a]) {
max = a;
}
if (b < heapSize && nums[max] < nums[b]) {
max = b;
}
if (max != i) {
swap(nums, i, max);
maxHeapify(nums, max, heapSize);
}
}
static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}