
正文
LeetCode 腾讯精选50题--数组中的第K个最大元素
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
好吧,不得不承认,书上看到的始终不是自己的,只有亲身时间过才会明白该怎么操作。
找数组中第K个最大元素,简而言之就是先排序,不论使用哪种算法,都需要先排序,确认位置,由于数组可以通过下标直接访问,所以我打算将数组按逆序排序,选择算法方面,一开始打算使用大顶堆的堆排序,可是想了下,快排的性能会更好一点,所以就采用快排了
具体思路如下:
由于一开始为了让空间复杂度为O(1),所以踩了不少坑,最坑的就是找到中间位置,又要让比中间元素小的放在左边,又不打算移动中间位置,直接就崩了。。。惨惨惨。
言归正传:
1. 首先明确一点就是快排使用递归操作
2. 其次利用三元法确定pivot,即元素的界,值小于pivot放在右侧,大于pivot的但在左侧
3. 根据k的大小确定递归哪一侧
具体程序如下:
package algorithm;
public class QuickSort {
public int findKthLargest(int[] nums, int k){
if(nums.length < k){
return 0;
}
quickSort(nums,0,nums.length-1,k);
return nums[k-1];
}
private void quickSort(int[] nums,int left,int right,int k){
int center = (left+right)/2;
if(left >= right){
return;
}
int pivot = chosePivot(nums,left,right,center);
int i = left+1;
int j= right-1;
while (i < j){
while (nums[i++] >= nums[center] && i < center){
i++;
}
while (nums[j--] < nums[center] && j > center){
j--;
}
if(nums[i] <= pivot && pivot <= nums[j]){
swap(nums,i,j);
if(i == center){
center = j;
}else if(j == center){
center = i;
}
}
}
if(k <= center){
quickSort(nums,left,center,k);
}else if(k > center){
quickSort(nums,center+1,right,k);
}
}
private int chosePivot(int[] nums,int left,int right,int center){
if(nums[right] > nums[center]){
swap(nums,right,center);
}
if(nums[left] < nums[right]){
swap(nums,left,right);
}
if(nums[left] < nums[center]){
swap(nums,left,center);
}
return nums[center];
}
private void swap(int[] nums,int left,int right){
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
public static void main(String[] args){
int[] nums = new int[]{3,2,1,5,6,4};
QuickSort sort = new QuickSort();
System.out.println(sort.findKthLargest(nums,2));
for (int i: nums){
System.out.print(i);
}
}
}
后续会在继续考虑优化问题,展示先这样了






