// 面试题40:最小的k个数
// 题目:输入n个整数,找出其中最小的k个数。例如输入4、5、1、6、2、7、3、8
// 这8个数字,则最小的4个数字是1、2、3、4。 #include <set>
#include <vector>
#include <iostream>
#include <functional> using namespace std; // ====================方法1====================
//使用Partition函数,利用快排思想找到前K个数
/*Random Partition*/
int RandomInRange(int min, int max)
{
int random = rand() % (max - min + ) + min;
return random;
} void Swap(int* num1, int* num2)
{
int temp = *num1;
*num1 = *num2;
*num2 = temp;
} int Partition(int data[], int length, int start, int end)//快排
{
if (data == nullptr || length <= || start < || end >= length)
throw new exception("Invalid Parameters"); int index = RandomInRange(start, end);//生成随机点
Swap(&data[index], &data[end]);//放到最后 int small = start - ;
for (index = start; index < end; ++index)//把数列中小于随机点的值放到前面
{
if (data[index] < data[end])
{
++small;
if (small != index)
Swap(&data[index], &data[small]);
}
} ++small;
Swap(&data[small], &data[end]);//然后把随机点放入小于它的值的后面 return small;
} /*核心算法*/
void GetLeastNumbers_Solution1(int* input, int n, int* output, int k)
{
if (input == nullptr || output == nullptr || k > n || n <= || k <= )
return; int start = ;
int end = n - ;
int index = Partition(input, n, start, end);
while (index != k - )
{
if (index > k - )
{
end = index - ;
index = Partition(input, n, start, end);
}
else
{
start = index + ;
index = Partition(input, n, start, end);
}
} for (int i = ; i < k; ++i)//可见改变了输入数组
output[i] = input[i];
} // ====================方法2====================
typedef multiset<int, greater<int> > intSet;//greater函数和less相反,这个谓词
typedef multiset<int, greater<int> >::iterator setIterator;//设置迭代器 void GetLeastNumbers_Solution2(const vector<int>& data, intSet& leastNumbers, int k)
{
leastNumbers.clear();//清空 if (k < || data.size() < k)
return; vector<int>::const_iterator iter = data.begin();//vector迭代器
for (; iter != data.end(); ++iter)
{
if ((leastNumbers.size()) < k)
leastNumbers.insert(*iter); else
{
setIterator iterGreatest = leastNumbers.begin();//multiset迭代器 if (*iter < *(leastNumbers.begin()))
{
leastNumbers.erase(iterGreatest);//删除该条目
leastNumbers.insert(*iter);//插入新的,自动排序
}
}
}
} // ====================测试代码====================
void Test(const char* testName, int* data, int n, int* expectedResult, int k)
{
if (testName != nullptr)
printf("%s begins: \n", testName); vector<int> vectorData;
for (int i = ; i < n; ++i)
vectorData.push_back(data[i]); if (expectedResult == nullptr)
printf("The input is invalid, we don't expect any result.\n");
else
{
printf("Expected result: \n");
for (int i = ; i < k; ++i)
printf("%d\t", expectedResult[i]);
printf("\n");
} printf("Result for solution1:\n");
int* output = new int[k];
GetLeastNumbers_Solution1(data, n, output, k);
if (expectedResult != nullptr)
{
for (int i = ; i < k; ++i)
printf("%d\t", output[i]);
printf("\n");
} delete[] output; printf("Result for solution2:\n");
intSet leastNumbers;
GetLeastNumbers_Solution2(vectorData, leastNumbers, k);
printf("The actual output numbers are:\n");
for (setIterator iter = leastNumbers.begin(); iter != leastNumbers.end(); ++iter)
printf("%d\t", *iter);
printf("\n\n");
} // k小于数组的长度
void Test1()
{
int data[] = { , , , , , , , };
int expected[] = { , , , };
Test("Test1", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
} // k等于数组的长度
void Test2()
{
int data[] = { , , , , , , , };
int expected[] = { , , , , , , , };
Test("Test2", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
} // k大于数组的长度
void Test3()
{
int data[] = { , , , , , , , };
int* expected = nullptr;
Test("Test3", data, sizeof(data) / sizeof(int), expected, );
} // k等于1
void Test4()
{
int data[] = { , , , , , , , };
int expected[] = { };
Test("Test4", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
} // k等于0
void Test5()
{
int data[] = { , , , , , , , };
int* expected = nullptr;
Test("Test5", data, sizeof(data) / sizeof(int), expected, );
} // 数组中有相同的数字
void Test6()
{
int data[] = { , , , , , , , };
int expected[] = { , };
Test("Test6", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
} // 输入空指针
void Test7()
{
int* expected = nullptr;
Test("Test7", nullptr, , expected, );
} int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
system("pause");
return ;
}

《剑指offer》第四十题(最小的k个数)的更多相关文章

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

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

  2. 剑指offer面试题30:最小的k个数

    一.题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.解题思路 1.思路1 首先对数组进行排序,然后取出前k个数 ...

  3. 《剑指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 ...

  4. 《剑指offer》第二十题(表示数值的字符串)

    // 面试题20:表示数值的字符串 // 题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如, // 字符串“+100”.“5e2”.“-123”.“3.1416”及“-1E-16 ...

  5. 《剑指offer》第十题(斐波那契数列)

    // 面试题:斐波那契数列 // 题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项. #include <iostream> using namespace std; ...

  6. 剑指Offer(三十二):把数组排成最小的数

    剑指Offer(三十二):把数组排成最小的数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/b ...

  7. 剑指Offer(三十四):第一个只出现一次的字符

    剑指Offer(三十四):第一个只出现一次的字符 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...

  8. 剑指Offer(二十四):二叉树中和为某一值的路径

    剑指Offer(二十四):二叉树中和为某一值的路径 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...

  9. 剑指Offer(二十九):最小的K个数

    剑指Offer(二十九):最小的K个数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...

  10. 剑指offer第四章

    剑指offer第四章 1.二叉树的镜像 二叉树的镜像:输入一个二叉树,输出它的镜像 分析:求树的镜像过程其实就是在遍历树的同时,交换非叶结点的左右子结点. 求镜像的过程:先前序遍历这棵树的每个结点,如 ...

随机推荐

  1. [lr] 矫正白平衡

    中性色区域 • 定义 中性色又称为无彩色系,是指由黑色.白色及由黑白调和成的各种深浅不同的灰色系列.中性色既不属于冷色调,也不属于暖色调.黑白灰是常用到的三大中性色.中性色区域是指不包含色彩的区域,准 ...

  2. Python基础socket编程

    Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 SocketServer, 它提供了服务器中心类,可以简化网络 ...

  3. VS2010/MFC编程入门之四十六(MFC常用类:MFC异常处理)

    上一节中鸡啄米讲了CFile文件操作类,本节主要来说说MFC异常处理. 在鸡啄米C++编程入门系列的最后一节鸡啄米:C++编程入门系列之五十(异常处理)中,鸡啄米讲了C++标准异常的处理机制,如果你还 ...

  4. lnmp之php5.6.29安装

    linux下lnmp环境之php安装 为了防止出现缺失,安装下面集成,复制的时候请将这个复制成一个整行,下面3行是一整行 [root@localhost src]# yum -y install gc ...

  5. python解决matplotlib中文坐标值乱码的问题

    加上这句话即可 plt.rcParams['font.sans-serif']=['SimHei'] 效果:

  6. python 读不同编码的文本,传递一个可选的encoding 参数给open() 函数

    文件的读写操作默认使用系统编码,可以通过调用sys.getdefaultencoding() 来得到.在大多数机器上面都是utf-8 编码.如果你已经知道你要读写的文本是其他编码方式,那么可以通过传递 ...

  7. Python: re.compile最短匹配模式,只取双引号内的值\“

    用正则表达式匹配某个文本模式 1.只取双引号内的值 2.长短匹配模式对比 贪婪模式:     模式r'\"(.*)\" '的意图是匹配被双引号包含的文本,但是这个表达式中*是贪婪的 ...

  8. Java SE 基础知识(String,Array)

    String 类: 1. 对于String对象的相等性判断来说,请使用equals()方法,而不是==.String的equals()是判断当前字符串与传进来的字符串的内容是否一致. 2. Strin ...

  9. C/C++之类型强制转化

    强制转化四种类型可能很多人都常常忽略就象我一样,但是有时还是比较有用的.不了解的建议看看,一些机制我也不是十分了解,只是将一些用法写出来让大家看看.                           ...

  10. [转载]INNER JOIN连接两个表、三个表、五个表的SQL语句

    SQL INNER JOIN关键字表示在表中存在至少一个匹配时,INNER JOIN 关键字返回行. 1.连接两个数据表的用法: FROM Member INNER JOIN MemberSort O ...