class Solution {
public int findKthLargest(int[] nums, int k) {
initHeap(nums);
for (int i = nums.length - 1; i > nums.length - k; i--) {
swap(nums,0,i);
heapSort(nums,0,i);
}
return nums[0];
}
public void initHeap(int[] nums) {
for (int i = nums.length / 2; i >= 0; i--) {
heapSort(nums,i,nums.length);
}
}
public void heapSort(int[] nums,int parent, int length) {
int left = 2 * parent + 1;
int right = left + 1;
int maxIndex = parent;
if (left < length && nums[left] > nums[maxIndex]) {
maxIndex = left;
}
if (right < length && nums[right] > nums[maxIndex]) {
maxIndex = right;
}
if (maxIndex != parent) {
swap(nums,maxIndex,parent);
heapSort(nums,maxIndex,length);
}
}
public void swap(int[] nums, int x, int y) {
int temp = nums[x];
nums[x] = nums[y];
nums[y] = temp;
}
}
2.快排+二分
class Solution {
public int findKthLargest(int[] nums, int k) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
//小于等于nums[mid]的数有mid个
int mid = fastOrder(nums,left,right);
//大于等于nums[mid]的有nums.length - mid个,当k = nums.length -mid时,nums[mid]就是第k大个数。
if (mid == nums.length - k) {
return nums[mid];
}else if (mid > nums.length - k) {
right = mid - 1;
}else {
left = mid + 1;
}
}
return -1;
}
public int fastOrder(int[] nums, int left, int right) {
int l = left;
int r = right;
while (l < r) {
while (l < r && nums[r] >= nums[left]) r--;
while (l < r && nums[l] <= nums[left]) l++;
swap(nums,l,r);
}
swap(nums,left,r);
return l;
}
public void swap(int[] nums, int x, int y) {
int temp = nums[x];
nums[x] = nums[y];
nums[y] = temp;
}
}
3.纯二分
class Solution {
public int findKthLargest(int[] nums, int k) {
//数组中最大值
int high = Integer.MIN_VALUE;
//数组中最小值
int low = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
if (nums[i] > high) high = nums[i];
if (nums[i] < low) low = nums[i];
}
//low 与high中元素个数
int count = 0;
while (low <= high) {
int mid = low + (high - low) / 2;
count = betweenCount(nums,mid,high);
if (count > k) {
low = mid + 1;
}else if (count < k) {
high = mid - 1;
k = k - count;
}else {
return minCount(nums,mid);
}
}
return high;
}
//nums数组中大于等于mid的有k个,找出最小的那个,就是第k大的元素
public int minCount(int[] nums, int mid) {
int compare = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
if (nums[i] >= mid && nums[i] < compare) {
compare = nums[i];
}
}
return compare;
}
//nums中大于等于start,且小于等于end的元素个数。
public int betweenCount(int[] nums, int start,int end) {
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] >= start && nums[i] <= end) {
count++;
}
}
return count;
}
}