博客
关于我
找中位数
阅读量:656 次
发布时间:2019-03-15

本文共 2451 字,大约阅读时间需要 8 分钟。

设计一个算法快速计算无序数列的中位数,时间复杂度为O(n)。

中位数的定义为:若数列元素个数为奇数,则为排序后中间的数;若为偶数,则为中间两个数的平均值。常规排序方法时间复杂度为O(n log n),但我们需要线性时间解决方案。快速选择算法(Quick Select)可满足这一需求,因为其平均时间复杂度为O(n)。

实现思路

  • 快速选择算法

    • 递归地选择数组中的基准元素,调整范围,直到找到精确的中位数位置。
    • 对于奇数个元素,找到中间的那个元素;对偶数个元素,分别找到中间两个元素的位置。
  • 平衡性考虑

    • 基准的选取策略直接影响算法的效率,选择中间位置的基准减少递归深度,确保O(n)时间复杂度。
  • 处理边界情况

    • 基准选取后,根据基准分割数组,确定下一步查找的方向。
    • 处理分割线等于当前基准时的特殊情况。
  • 代码实现

    import java.util.Scanner;public class zhongweishu {    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        while (sc.hasNext()) {            int n = sc.nextInt();            int[] a = new int[n];            for (int i = 0; i < n; i++) {                a[i] = sc.nextInt();            }            if (n % 2 != 0) {                int p = quickSelect(a, 0, n - 1, (n + 1) / 2);                System.out.println(p);            } else {                int mid1 = quickSelect(a, 0, n - 1, n / 2);                int mid2 = quickSelect(a, 0, n - 1, n / 2 + 1);                double avg = (mid1 + mid2) / 2.0;                System.out.printf("%.3f", avg);            }        }    }    private static int quickSelect(int[] a, int left, int right, int k) {        if (left == right) {            return a[left];        }        int pivot = ((new Random()).nextInt(right - left + 1) + left);        int temp = a[pivot];        a[pivot] = a[left];        a[left] = temp;        int i = left + 1;        int j = right;        while (i < j) {            if (a[i] > a[j]) {                if (i != left + 1) {                    a[pivot] = a[i];                    a[i] = a[left];                    a[left] = a[right];                    a[right] = a[pivot];                    pivot = left;                }                a[right] = a[j];                a[j] = a[right];                j--;            } else {                if (j != right) {                    a[pivot] = a[j];                    a[j] = a[right];                    a[right] = a[pivot];                    pivot = right;                }                a[right] = a[i];                a[i] = a[right];                i++;            }        }        if (pivot < k) {            return quickSelect(a, pivot + 1, right, k);        } else {            return quickSelect(a, left, pivot - 1, k);        }    }}

    代码解释

    • 主函数:读取输入,调用快速选择函数找到中位数,输出结果。
    • 快速选择函数:使用中间点的随机选择作为基准,将数组分割为三部分。根据基准位置,确定下一步查找范围。
    • 分割策略:基准随机选取,通过交换元素位置,并调整查找范围,确保每次查找范围减少。

    这种方法确保了在线性时间内找到数列的中位数,适用于大规模数据处理。通过合理的分割策略,算法在各个情况下均能有效运行。

    转载地址:http://nmkqz.baihongyu.com/

    你可能感兴趣的文章
    Error:Cannot read packageName from AndroidManifest.xml
    查看>>
    【自学Flutter】4.1 Material Design字体图标的使用(icon)
    查看>>
    【换行符】什么时候用cin.get()吃掉输入流中的换行符
    查看>>
    广东外语外贸大学第三届网络安全大赛Writeup
    查看>>
    SpringBoot使用RedisTemplate简单操作Redis的五种数据类型
    查看>>
    Thymeleaf sec:authorize 标签不生效
    查看>>
    微信JS-SDK DEMO页面和示例代码
    查看>>
    测试tensorflow是否安装成功 出现 SyntaxError: invalid syntax的错误
    查看>>
    Flask--简介
    查看>>
    Frame--Api框架
    查看>>
    Boostrap技能点整理之【网格系统】
    查看>>
    javaWeb服务详解(含源代码,测试通过,注释) ——Emp的Dao层
    查看>>
    Git简单理解与使用
    查看>>
    echarts 基本图表开发小结
    查看>>
    adb通过USB或wifi连接手机
    查看>>
    JDK9-15新特性
    查看>>
    TreeSet、TreeMap
    查看>>
    JVM内存模型
    查看>>
    可变长度参数
    查看>>
    3、条件查询
    查看>>