题目
中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数(或最中间两个数据的平均数). 给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)
思路
查找中位数问题可以转化为TOP k问题(即查找第k小的元素问题)。
-
若数组长度为偶数,以数组{8,1,3,4,7,6}为例,则令 k = nums.length / 2,找到第k小的数(对应数组下标为k-1)和第k+1小(对应数组下标为k)的数4和6,取平均值,即是中位数。
-
若数组长度为奇数,以数组{8,1,3,4,7}为例,则找到第k+1小(对应数组下标为k)的数4,即是中位数。
TOP问题:查找第k小的元素。可采用快排算法思想和冒泡排序算法思想。排序算法比较常见,不一一讲述。
代码
快排思想
public static int FindMedium(int[] nums){
if(nums.length % 2 == 0){
return (findK2(nums.length / 2 -1,nums) +
findK2(nums.length / 2,nums))/2;
}else {
return findK2(nums.length / 2,nums);
}
}
/**
* 找到第k+1小的数
* 使用快排
* @param nums 数组
* @return
*/
public static int findK2(int k,int[] nums){
return quicksort(0,nums.length-1,nums,k);
}
public static int quicksort(int left,int right,int[] nums,int k){
int mid = partion(left, right, nums);
if(mid == k){
return nums[mid];
}
else if(mid < k){
return quicksort(mid+1, right, nums,k);
}
else {
return quicksort(left, mid-1, nums,k);
}
}
public static int partion(int left,int right,int[] nums){
int l = left;
int r = right;
int midnum = nums[l];
while (l<r){
while (l<r && nums[r] >= midnum){
r--;
}
nums[l] = nums[r];
while (l<r && nums[l] <= midnum){
l++;
}
nums[r] = nums[l];
}
nums[l] = midnum;
return l;
}
冒泡排序思想
public static int FindMedium(int[] nums){
if(nums.length % 2 == 0){
return (findK1(nums.length / 2 -1,nums) +
findK1(nums.length / 2,nums))/2;
}else {
return findK1(nums.length / 2,nums);
}
}
/**
* 找到第k+1小的数
* 冒泡排序
* @param nums 数组
* @return
*/
public static int findK1(int k,int[] nums){
int len = nums.length;
for(int i=0;i<=k;i++){
for(int j=i+1;j<len;j++){
if(nums[i] > nums[j]){
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
}
return nums[k];
}