題目
中位數定義:一組數據按從小到大的順序依次排列,處在中間位置的一個數(或最中間兩個數據的平均數). 給出一組無序整數,求出中位數,如果求最中間兩個數的平均數,向下取整即可(不需要使用浮點數)
思路
查找中位數問題可以轉化爲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];
}