使用Partition方法找数组的中位数

使用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);
    }

}

附 一次快排过程

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以使用快速选择算法来解决这个问题,快速选择算法的思路类似于快速排序,但是只需要定位到第 k 小的元素(在本题中 k 为数组长度的一半)。 具体实现步骤如下: 1. 选数组中的一个元素作为 pivot。 2. 将数组分为两部分:小于 pivot 的部分和大于等于 pivot 的部分。 3. 如果小于 pivot 的部分的长度大于等于 k,那么说明中位数在小于 pivot 的部分中,对小于 pivot 的部分递归执行快速选择算法。 4. 如果小于 pivot 的部分的长度小于 k,那么说明中位数在大于等于 pivot 的部分中,对大于等于 pivot 的部分递归执行快速选择算法。 5. 当小于 pivot 的部分的长度正好为 k 时,pivot 即为中位数。 下面是 Java 代码实现: ``` public static int findMedian(int[] nums) { int k = nums.length / 2; int left = 0, right = nums.length - 1; while (left <= right) { int pivotIndex = partition(nums, left, right); if (pivotIndex == k) { return nums[pivotIndex]; } else if (pivotIndex < k) { left = pivotIndex + 1; } else { right = pivotIndex - 1; } } return -1; } private static int partition(int[] nums, int left, int right) { int pivot = nums[left]; int i = left; for (int j = left + 1; j <= right; j++) { if (nums[j] < pivot) { i++; swap(nums, i, j); } } swap(nums, i, left); return i; } private static void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } ``` 其中,`partition` 方法用于实现快速排序中的分区操作,将小于 pivot 的元素移动到数组的左侧,大于等于 pivot 的元素移动到数组的右侧。`findMedian` 方法则是快速选择算法的主要实现,用于数组中位数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值