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

题目描述

  有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和Sb,Sa中的元素大于等于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 欢迎转载,也请保留这段声明。谢谢!

  

寻找最大的k个数的更多相关文章

  1. 算法系列:寻找最大的 K 个数

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  2. 算法练习:寻找最小的k个数

    参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...

  3. 编程之美2.5:寻找最大的K个数

    编程之美2.5:寻找最大的K个数 引申:寻找第k大的数: 方法一: // 选择第k大的数(通过改进快速排序来实现) public static void SelectShort(int[] array ...

  4. 第2章 数字之魅——寻找最大的K个数

    寻找最大的K个数 问题描述 在面试中,有下面的问答: 问:有很多个无序的数,我们姑且假定它们各不相等,怎么选出其中最大的若干个数呢? 答:可以这样写:int array[100] …… 问:好,如果有 ...

  5. O(N)的时间寻找最大的K个数

    (转:http://www.cnblogs.com/luxiaoxun/archive/2012/08/06/2624799.html) 寻找N个数中最大的K个数,本质上就是寻找最大的K个数中最小的那 ...

  6. 03寻找最小的k个数

    题目描述:查找最小的k个元素         题目:输入n个整数,输出其中最小的k个.         例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 1:最简单 ...

  7. 寻找最大的k个数问题

    这是编程之美书第2.5节的一道题目. 各种解法: 解法一,用nlgn复杂度的排序算法对数组进行从大到小排序,取前K个.但这方法做了两件不必要做的事:它对想得到的K个数进行了排序,对不想得到的n-K个数 ...

  8. 算法笔记_035:寻找最小的k个数(Java)

    目录 1 问题描述 2 解决方案 2.1 全部排序法 2.2 部分排序法 2.3 用堆代替数组法 2.4线性选择算法   1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 ...

  9. Java实现寻找最小的k个数

    1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 解决方案 2.1 全部排序法 先对这n个整数进行快速排序,在依次输出前k个数. package com.liuzhen. ...

  10. 【编程之美】2.5 寻找最大的k个数

    有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2 ...

随机推荐

  1. JAVA转让JS功能

    今天,在发展中使用js和Java互动.通常我们使用更多的是js转让Java方法.可以使用dwr.Ajax.jquery.突然发现Java转让js然后,我真的没见过,今天,互联网提供以下信息,顺便总结: ...

  2. HDU 4831 Scenic Popularity (段树)

    Scenic Popularity Problem Description 临近节日,度度熊们近期计划到室外游玩公园.公园内部包含了非常多的旅游景点区和歇息区,因为旅游景点非常热门,导致景点区和歇息区 ...

  3. 解决Unity3d 4.3 动画系统带来的烦恼

    近期有非常多同学问我关于unity3d 4.3更新之后动画系统和曾经不一样了,并且之前用的非常熟练的创建动画和修修改画非常多操作都不好用了,那么在这里和大家分享一下三杀的个人经验,方便大家使用unit ...

  4. C++ Primer中文本查询演示样例Query的实现

    近期在看C++ Primer复习C++的语法,看到书中15.9章中的文本查询演示样例时,认为设计得非常不错,于是便动手照着实现了一个,改动了非常久最终执行成功了,从中也学习到了非常多的语法.以下把实现 ...

  5. 【翻译】C#和.NET核心快速参考

    原文:[翻译]C#和.NET核心快速参考 PS:在网上看到的一篇C#总结,英文的,总结的还可以,都是基础知识,翻译给大家学习.文章结尾有英文原版.发布地址:http://www.cnblogs.com ...

  6. 虚拟WiFi

    转载用WinForm写一个虚拟WiFi助手玩玩(附源码)   这早不是什么新鲜的东西了,同类软件已经有很多,但不是收费就是有广告,在学校的时候就想自已写一个了,但那时候啥也没学,对C的掌握程度也就是定 ...

  7. curl 简单使用

    cURL -- Command Line URL viewer -u username:password 以 Basic 方式发送用户名和密码 -d 以 POST 方式发送数据 -X 支持其它动词, ...

  8. TypeScript入门

    博客园首发,转载请注明出处,多谢支持.http://www.cnblogs.com/xuema/ 一.TypeScript TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaSc ...

  9. Appium Android Bootstrap源码分析之命令解析执行

    通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在b ...

  10. 实现关闭ssh继续实施方案---tmux

    问题1:为什么ssh一个关闭.不再执行的程序 罪魁祸首:SIGHUP 信号 让我们来看看为什么关掉形式/断开将使程序被执行死. 在Linux/Unix在.有几个概念: 进程组(process grou ...