【面试题030】最小的k个数
题目:
    输入n个整数,找出其中最小的k个数。
    例如输入4、5、1、6、2、7、3、8这8个字,则其中最小的4个数字是1、2、3、4。
 
 
思路一:
    可以同样的基于随机快速排序的Partition函数,来对数组做划分,
    基于k来作调整,返回调用Partition函数,直到左边的k个数字是整个数组中最小的k个数字。
    ps.这种方法要修改数组中数字的顺序,因为Partition函数会调整数组中数字的顺序。
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 
#include <iostream>

using namespace std;

void Swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

int Partition(int *numbers, int beg, int end)
{
//如果轴是随机取的话,这里得做一个Swap把这个轴元素交换到end位置
    int small = beg - 1;
    int index;
    for (index = beg; index < end; ++index)
    {
        if (numbers[index] <= numbers[end])
        {
            small++;
            Swap(&numbers[small], &numbers[index]);
        }
    }
    ++ small;
    Swap(&numbers[small], &numbers[end]);
    return small;
}

void GetLeastNumbers(int *input, int n, int *output, int k)
{
    if (input == NULL || output == NULL || k > n || n <= 0 || k <= 0)
    {
        return;
    }
    int start = 0;
    int end = n - 1;
    int index = Partition(input, start, end);
    while (index != k - 1)
    {
        if (index > k - 1)
        {
            end = index - 1;
            index = Partition(input, start, end);
        }
        else
        {
            start = index + 1;
            index = Partition(input, start, end);
        }
    }
    for (int i = 0; i < k; ++i)
    {
        output[i] = input[i];
    }

}

int main()
{
    int input[] = {4, 5, 1, 6, 2, 7, 3, 8};
    int output[4];
    int num = sizeof(input) / sizeof(input[0]);
    int k = sizeof(output) / sizeof(output[0]);
    GetLeastNumbers(input, num, output, k);
    for (int i = 0; i < k; ++i)
    {
        cout << output[i] << " ";
    }
    cout << endl;
    return 0;
}

 
 
思路二:
    首先创建一个大小为k的容器来存储最小的k个数字,
    遍历这n个数字,如果容器大小小于k,就放入。如果容器已经满了,则跟容器中的最大数字做比较,
    如果大于最大数字,遍历下一个,如果小于当前已有的最大值,替换当前这个最大值。
    如果用二叉树来实现这个容器,那么我们能在O(logk)
——我想到了最大堆,在O(1)时间内获得已有的k个数字中的最大值,但是需要O(logk)时间完成删除及插入操作。
    我们可以利用红黑树来实现我们的容器,STL中set和multiset都是基于红黑树实现的。
 
 
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
#include <iostream>
#include <set>
#include <vector>
using namespace std;

typedef multiset<int, greater<int> > intSet;
typedef multiset<int, greater<int> >::iterator setIterator;

void GetLeastNumbers(const vector<int> &data, intSet &leastNumbers, int k)
{
    leastNumbers.clear();
    if ( k < 1 || (int)data.size() < k )
    {
        return;
    }

vector<int>::const_iterator iter = data.begin();
    for (; iter != data.end(); ++iter)
    {
        //有符号数/无符号数不匹配
        if ((int)(leastNumbers.size()) < k)
        {
            leastNumbers.insert(*iter);
        }
        else
        {
            setIterator iterGreatest = leastNumbers.begin();

if (*iter < * (leastNumbers.begin()))
            {
                leastNumbers.erase(iterGreatest);
                leastNumbers.insert(*iter);
            }
        }
    }
}

int main()
{
    int input[] = {4, 5, 1, 6, 2, 7, 3, 8};
    intSet leastNumbers;
    vector<int> data(&input[0], &input[7]);
    GetLeastNumbers(data, leastNumbers, 4);

while(!leastNumbers.empty())
    {
        setIterator iterGreatest = leastNumbers.begin();
        cout << *iterGreatest << " ";
        leastNumbers.erase(iterGreatest);
    }

cout << endl;
    return 0;
}

 
 

【面试题030】最小的k个数的更多相关文章

  1. 剑指Offer:面试题30——最小的k个数(java实现)

    问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...

  2. 面试题30.最小的k个数

    题目:输入n个整数,找出其中最小的k个数,例如输入4,5,1,6,2,7,3,8 这8个数字,则最小的四个数字为1,2,3,4, 这道题是典型的TopK问题,剑指Offer提供了两种方法来实现,一种方 ...

  3. 剑指offer 面试题40. 最小的k个数

    O(N)划分法,注意这个方法会改变原数据(函数参数是引用的情况下)!当然也可以再定义一个新容器对其划分 要求前k小的数,只要执行快排划分,每次划分都会把数据分成大小两拨.直到某一次划分的中心点正好在k ...

  4. leetcode 签到 面试题40. 最小的k个数

    题目 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k = ...

  5. 《剑指offer》面试题40. 最小的k个数

    问题描述 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k ...

  6. java实现——030最小的k个数

    1.O(nlogk)海量数据 import java.util.TreeSet; public class T030 { public static void main(String[] args){ ...

  7. 【剑指Offer面试题】 九度OJ1371:最小的K个数

    题目链接地址: http://ac.jobdu.com/problem.php?pid=1371 题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265 ...

  8. 面试题40:最小的 k 个数

    import java.util.Arrays; /** * Created by clearbug on 2018/2/26. * * 面试题40:最小的 k 个数 * * 注意:因为前两天在陌陌面 ...

  9. 剑指Offer面试题:27.最小的k个数

    一.题目:最小的k个数 题目:输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 这道题是典型的TopK问题,其最简单的思路莫过于 ...

随机推荐

  1. JQuery Pagination 分页插件 增加了首页尾页以及跳转功能

    JQuery分页插件 挺好用的 但是官方是没有提供首页尾页以及跳转功能 我觉得这个功能可以有,于是就改进了一下 一个js一个css从连接里面下 链接:http://pan.baidu.com/s/1n ...

  2. ASP.NET MVC强制返回XML

    GlobalConfiguration.Configuration.Formatters.Remove(config.Formatters.JsonFormatter);

  3. linux远程客户端putty,xshell搭建注意事项——《视频》

    本视频放在云端,点击此链接即可播放:              http://www.tudou.com/programs/view/75QMh0-DQfA/               崇尚开源,热 ...

  4. rinetd 安装使用

    1 下载解压: wget http://www.boutell.com/rinetd/http/rinetd.tar.gz tar zxvf rinetd.tar.gz 2 手动建立目录 mkdir ...

  5. PHP流程控制语句下

    ok,继续搞. while循环: while(expr){ 程序块: } 条件expr成立执行程序块,否则结束. do while循环:do while循环比while循环要多循环一次,它要先执行程序 ...

  6. jqueryGrid 内置的onclickSubmit afterSubmit

    $(document).ready(function() { $('#jpgCustomers').jqGrid({ //url from wich data should be requested ...

  7. Hive内表和外表的区别

    本文以例子的形式介绍一下Hive内表和外表的区别.例子共有4个:不带分区的内表.带分区的内表.不带分区的外表.带分区的外表. 1 不带分区的内表 #创建表 create table innerTabl ...

  8. Redis 二:入门基本篇

    .多数据库设置 - ,代表16个数据库 .glob风格通配符 keys * 返回所有 keys ba? 返回 bar keys b[a-z][a-z] 返回btt bar \x 匹配转义字符 .判断一 ...

  9. sysfs分析

      Linux设备模型——设备驱动模型和sysfs文件系统解读 内核版本:2.6.30 1. What is sysfs? 个人理解:sysfs向用户空间展示了驱动设备的层次结构.我们都知道设备和对应 ...

  10. C++中的冒泡排序,选择排序,插入排序

    最简单的插入排序:思想,两两之间比较,时间复杂度o(n^2) void bubblesort(vector<int>&vec, int n) { if (&vec==NUL ...