zoukankan      html  css  js  c++  java
  • 寻找最大的k个数

      这个题目是非常经典的一个题目,解法也有很多,现在就把我已经理解的解法记录下来。

    题目描述

      有n个无序的数,它们各不相等,怎样选出其中的最大的k个数呢?

    题目分析:

    解法1:

      最容易想到的就是把n个数进行排序,然后选择最大的k个数。排序算法很多,快速排序和堆排序都是不错的选择,他们的复杂度都是Ο(n*log2n),然后取出前k个Ο(k),总的时间复杂度可以看成是Ο(n*log2n)

      在这个解法中,对n个数进行了排序,如果n的数值非常大的话,会很慢。

    解法2:

      能不能只遍历一边n个数就能把最大的k个数选出来呢?答案是可以的。

      在解法2中,规定,n个数存储在数组array[n]中,我们需要开辟k个数的空间result[k]。遍历的最终目的是把最大的k个数存储在result[k]中。每一步的过程是,当遍历到array[i]时,判断array[i]是否比result[]中最小的数大,如果是,则表明,array[i]应该出现在result[]中(此时假设result[]中已存满k个数)。

      那么应该用什么样的方式来进行此过程呢?其实这个也比较好想。

    •   最直观的就是采用插入排序,把不合适的挤出去。这个方法复杂度为Ο(k),总共为Ο(n*k).
    •   还有一种方法是采用最小堆存储result[],每次取出最小堆最小的比较,如果比他大,则交换,并且堆进行一次调整。这个方法复杂度为Ο(log2k),总共为Ο(n*log2k).

    解法3:

      这个方法是编程之美里讲到的。(其实上个解法编程之美里也提到过,不过也是我自己想到的)

      这个方法借鉴快排的思路。假设n个数存储在数组S[]中,从S中随机找到一个元素X,把数组分成两部分Sa和SbSa中的元素大于等于X,Sb中的元素小于X。此时,

    1. Sa中的元素个数小于k,则k个最大的元素为Sa中的元素加上Sb中的k-|Sa|个元素
    2. Sa中的元素个数大于或等于k,则需要返回Sa中最大的k个元素

      这时候已经非常明了了,需要用到递归的方法来计算method1中的Sb中的k-|Sa|个元素以及method2中的Sa中最大的k个元素。这个算法的时间复杂度为Ο(n*log2k)。

    其他

      可能需要考虑特殊情况。

      如果n不是很大,并且都是整数的话,若MAX为n个数中最大的数,可以开辟int array[MAX+1],其中存储数i的个数。都输进去,需要用到n此,然后从MAX开始,找到k个最大的数;如果n个数都不相同,可以开辟MAX+1个bit型的,只用表明存在或不存在。这样的解法是线性的。但如果不是整数或者MAX相当大的话这种方法就不好使了。

      肯定还有其他更好的解法的,但是因为我现在还没有掌握,暂时写到这里。

    作者:viczzx 出处:http://www.cnblogs.com/zixuan-zhang 欢迎转载,也请保留这段声明。谢谢!

      

  • 相关阅读:
    【BZOJ1835】[ZJOI2010]base 基站选址 线段树+DP
    【BZOJ1786】[Ahoi2008]Pair 配对 DP
    【BZOJ3956】Count 主席树+单调栈
    【BZOJ4605】崂山白花蛇草水 权值线段树+kd-tree
    【BZOJ2597】[Wc2007]剪刀石头布 最小费用流
    前端学习笔记之CSS属性设置
    前端学习笔记之HTML body内常用标签
    前端学习笔记之CSS介绍
    前端学习笔记之CSS选择器
    博客园美化技巧汇总
  • 原文地址:https://www.cnblogs.com/zixuan-zhang/p/3328321.html
Copyright © 2011-2022 走看看