持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
1、前言
每天一个算法小练习,本篇使用Java实现。
2、题目描述
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
- 1 <= k <= nums.length <= 105
- -104 <= nums[i] <= 104
2.1、示例1
输入: [3,2,1,5,6,4], k = 2
输出: 5
2.2、示例2
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
3、解题思路
3.1、快排
快速排序是一种既高效,又不怎么浪费空间的排序算法。它以选中的基准数来进行多次的比较与交换来完成排序。这个过程由多次重复单趟排序组成,可以把它理解为冒泡排序+递归分治。对于每一次单趟排序:选中一个基准数 k,让 k 的左边的所有数小于 k,k 的右边都大于 k。那么对于 k 来说,它已经被排好序了。下面就对 k 的左右两边进行上述操作,每次排序好一个基准数,最终整个数组就是有序的。
public int findKthLargest(int[] nums, int k) {
return quickSort(nums, 0, nums.length - 1, k);
}
/**
* 快排
* @param nums
* @param left
* @param right
* @param k
* @return
*/
public int quickSort(int[] nums, int left, int right, int k){
while(left <= right){
int mid = partition(nums,left,right);
// 数组长度 - k = 第K个最大元素的索引
int target = nums.length - k;
if(mid == target){
return nums[mid];
}else if(mid < target){
left = mid + 1;
}else {
right = mid - 1;
}
}
return -1;
}
public int partition(int[] nums, int left, int right){
int pivot = nums[right];
while(left < right){
while(left < right && nums[left] <= pivot){
left++;
}
if(left < right){
swap(nums,left,right);
right--;
}
while(left < right && nums[right] >= pivot){
right--;
}
if(left < right){
swap(nums,left,right);
left++;
}
}
return left;
}
/**
* 交换值
* @param nums
* @param left
* @param right
*/
public void swap(int[] nums, int left, int right){
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
执行结果:
-
时间复杂度:。
-
空间复杂度:。
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊