快速选择可以在nlogn的时间复杂度下得到一组无序数字的第k大,原理基于快速排序,每次以某个数字为中点分成的左右两段,左边都小于等于分割数,而右边都大于等于分割数,快速选择的求解速度要比全部排序后再取第k大快
/**
* Created by tcgogogo on 16/8/18.
*/
class Solution {
public void outPut(int[] nums) {
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
System.out.println();
}
public void swap(int[] nums, int i, int j) {
if (i == j) {
return;
}
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public void quickSort(int[] nums, int left, int right) {
if (left > right) {
return;
}
int i = left, j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left]) {
j --;
}
while (i < j && nums[i] <= nums[left]) {
i ++;
}
if(i < j) {
swap(nums, i, j);
}
}
swap(nums, left, i);
quickSort(nums, left, i - 1);
quickSort(nums, i + 1, right);
}
public int quickSelect(int[] nums, int left, int right, int k) {
if (left > right) {
return 0;
}
int i = left, j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left]) {
j --;
}
while (i < j && nums[i] <= nums[left]) {
i ++;
}
swap(nums, i, j);
}
swap(nums, left, i);
if(k == i - left + 1) {
return nums[i];
}
else if(k < i - left + 1) {
return quickSelect(nums, left, i - 1, k);
}
else {
return quickSelect(nums, i + 1, right, k - (i - left + 1));
}
}
}