• k-选取问题


    一、k-选取问题:
    给定任意一个可比较的序列,从中找出第k个元素(k从0开始,默认是从小到大的次序)的问题称为k-选取(k-selection)。
    k-选取问题有两种退化的情况:
    1、0-选取问题即是找出序列的最小值问题。
    2、(length-1)-选取问题即是找出序列的最大值问题。
    以上两中问题都有最优解,都可以在线性的时间复杂度内求解。

    k-选取问题的另一个常见的问题是中位数问题:
    严格来说:
    1、如果序列的长度为奇数,其中位数为ary[length/2]
    2、如果序列的长度为偶素,其中位数为(ary[length/2-1]+ary[length/2])/2

    但是可以稍作简化,统一规定序列中位数为索引为length/2的元素。

    二、k-选取问题的一般解:

        //此非递归的版本实际为减治思想
        public static int kSelection(int[] ary,int k){
            int length = ary.length;
            if (k < 0 || k > length-1) {return -1;}//k值不在范围内
            int index,low = 0,high = length-1;
            while(true){
                index = position(ary, low, high);
                if (index == k) {break;}//命中,返回
                if (index < k) {//k必然会在index+1和high之间
                    low = index+1;
                }else {//k必然会在low1和index-1之间
                    high = index-1;
                }
            }
            return index;
        }

    三、主流数问题

    除此之外,还有一个与之稍有关联的问题时序列主流数问题:
    若序列中有一半以上的值(此处定义为严格大于一半)同为m,这该值m称为该序列的主流数。

    不难发现,如果某序列有主流数m,则经过排序后,ary[length/2]必定等于该序列的主流数。

        public static boolean hasMajority(int[] ary){
            int length = ary.length;
            int index = kSelection(ary,length/2);//k为length/2
            int count = 0;
            for (int i = 0; i < length; i++) {
                if (ary[i] == ary[index]) {
                    count++;
                }
            }
            return count > length/2;//如果存在主流数,ary[index]重复次数必然大于length/2
        }
  • 相关阅读:
    【java基础操作】
    IDEA使用总结
    【Linus安装Jenkins】
    【Linus安装Docker】
    【Linus搭建Harbor环境】
    Markdown
    【Python】01.环境搭建
    【01-自动化测试环境搭建】
    【MongoDB入门】
    java语言程序设计 **10.25 第十章练习题 string类中split函数实现
  • 原文地址:https://www.cnblogs.com/qcblog/p/7565637.html
Copyright © 2020-2023  润新知