快排进行划分:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
public static void main(String[] args){
int[] nums = {2,4,3,6,1,5};
Solution s = new Solution();
int k = 3;
int res = s.findkminNum(k,0,5,nums);
System.out.println(res);
}
public int findkminNum(int k,int start,int end,int[] nums){
if(k==0||k>end-start+1||end<start) return -1;
int key = nums[end];
int i = start-1;
for(int j=start;j<end;j++){
if(nums[j]<key){
i++;
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
i++;
int tmp = nums[i];
nums[i] = nums[end];
nums[end] = tmp;
int partition = i;
if(partition-start+1==k) return nums[partition];
else if(partition-start+1>k) return findkminNum(k,start,partition-1,nums);
else return findkminNum(k-(partition-start+1),partition+1,end,nums);
}
}
讲解得比较详细的博客: http://www.yalewoo.com/quickselect_and_linearselect.html
下面这种方法思路"巧妙"?个人觉得很不够直观,编程到一半比较懒,暂且记录下来,挖个坑
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
public static void main(String[] args){
int[] nums = {2,4,3,6,1,5};
Solution s = new Solution();
int k = 3;
int res = s.findkminNum(k,nums);
System.out.println(res);
}
public int findkminNum(int k, int[] nums){
int n = nums.length;
int sub = n/5;
for(int i=0;i<sub;i++){
int[] elem = new int[5];
for(int j=0;j<5;j++){
if(5*i+j<n) elem[j]=nums[5*i+j];
/*
* insert sort --- start
*/
int pos = j;
int tmp = nums[pos];
while(j>0&&elem[j-1]>elem[pos]){
j--;
}
for(int h=pos;h>j;h--){
elem[h]=elem[h-1];
}
elem[j] = tmp;
/*
* insert sort --- end
*/
}
for(int j=0;j<5;j++){
if(5*i+j<n) nums[5*i+j] = elem[j];
}
}
int[] mediumArray = new int[sub];
for(int i=0;i<sub-1;i++){
mediumArray[i] = nums[5*i+2];
}
if(n%5>=3||n%5==0) mediumArray[sub-1] = nums[5*(sub-1)+2];
if(n%5<3||n%5!=0) mediumArray[sub-1] = nums[n-1];
int partition = findkminNum((sub+1)/2,mediumArray);
int countSmaller = 3*((sub+1)/2);
int countBigger = 3*(n-(sub+1)/2);
int partition2
if(k==partition)
return k;
}
}