使用Partition方法找数组的中位数
假如现在有一个长度为奇数的数组 {49, 38, 65, 97, 76, 13, 27, 49, 100}
现在想找到这个数组的中位数。
思路1:
先对数组进行排序,排序后的结果是{13, 27, 38, 49, 49, 65, 76, 97, 100},中位数就是数组中下标为n/2的数(49)。排序的时间复杂度最好情况下是O(nlogn),空间复杂度O(1)。
思路2:
由于我们的目标是找到中位数,不需要把每一个数都排好序,因此还有优化的空间。除了排序以外,我们还可以用快排中的Partition思想。
首先,随机选取一个数作为分类的标准,比它小的都放在它左边,比它大的都放在它右边。
如果这个数的下标刚好是n/2 ,那么这个数就是中位数;
如果这个数的下标小于n/2,说明中位数在它的右边;
如果这个数的下标大于n/2,说明中位数在它的左边
这是一个典型的递归过程~
Java代码如下:
public int findMiddleByPartition(int[] array, int left, int right) {
int i = left, j = right;
int key = array[left];
while(i < j) {
// j向左走,直到找到一个小于key的数
while(i < j && array[j] >= key) j--;
if(i < j) {
array[i] = array[j];
i++;
}
// i向右走,直到找到一个大于key的数
while(i < j && array[i] <= key) i++;
if(i < j) {
array[j] = array[i];
j--;
}
}
array[i] = key;
if(i == array.length / 2) {
return i;
}else if(i < array.length / 2){
return findMiddleByPartition(array, i + 1, right);
}else {
return findMiddleByPartition(array, left, i - 1);
}
}
附 一次快排过程