题目描述:给定整数数组 nums
和整数 k
,请返回数组中第 k
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
解题思路:快排、堆排序
解法一:快排
public class Solution {
public int findKthLargest(int[] nums, int k) {
myQuickSort(nums,0, nums.length - 1);
return nums[nums.length - k];
}
// 快排
public void myQuickSort(int[] nums, int low, int high) {
int i = low, j = high;
if (i < j) {
int temp = nums[i];
while (i != j) {
while (j > i && nums[j] >= temp) {
j--;
}
nums[i] = nums[j];
while (i < j && nums[i] <= temp) {
i++;
}
nums[j] = nums[i];
}
nums[i] = temp;
myQuickSort(nums, low, i-1);
myQuickSort(nums, i+1, high);
}
}
}
解法二:堆排序
public class Solution {
public int findKthLargest(int[] nums, int k) {
heapSort(nums);
return nums[nums.length - k];
}
// 堆排
public void heapSort(int[] arr) {
//构建大顶堆
for (int i = arr.length / 2 - 1; i >= 0; i--) {
//从第一个非叶子节点从下至上,从左至右调整结构
adjustHeap(arr, i, arr.length);
}
// 调整堆结构+交换堆顶元素与末尾元素
for (int j = arr.length - 1; j > 0; j--) {
swap(arr, 0, j);
adjustHeap(arr, 0, j);
}
}
public void adjustHeap(int[] arr, int i, int length) {
int temp = arr[i];
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) { //从i节点的左子节点开始,也就是2i+1处开始
if (k + 1 < length && arr[k] < arr[k + 1]) {
k++;
}
if (arr[k] > temp) {
arr[i] = arr[k];
i = k;
}else {
break;
}
}
arr[i] = temp;
}
public void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}