// 面试题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. STA分析(六) cross talk and noise

    在深亚微米技术(deep submicron)中,关于crosstalk和noise对design的signal integrate的影响越来越大.主要表现在glitch和对delay的影响. 1)m ...

  2. VS2010/MFC编程入门之四十八(字体和文本输出:文本输出)

    鸡啄米在上一节中讲了CFont字体类,本节主要讲解文本输出的方法和实例. 文本输出过程 在文本输出到设备以前,我们需要确定字体.字体颜色和输出的文本内容等信息.Windows窗口的客户区由应用程序管理 ...

  3. python写一个密码生成器的类,要求有个类变量,统计一下一共生成过多少个密码。 要求有4个方法,1:构造方法 2 实例方法 3 类方法 4 静态方法

    生成指定长度的随机数字密码 生成指定长度的随机字母密码 生成指定长度的随机数字和字母的混合 #encoding=utf-8   import random import string class pa ...

  4. Java EE业务处理流程与XML的引入

    Java EE基于MVC架构的业务处理流程 MVC架构业务处理流程 XML定义 XML是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言.XML被设计用于数据的存 ...

  5. excel第一次打开报错 向程序发送命令时出错 多种解决办法含终极解决方法

    excel第一次打开报错 向程序发送命令时出错 多种解决办法含终极解决方法 office2007应该遇到“向程序发送命令时出现 问题”,设置为以管理员运行也不好用,重装office也不好用,下面介绍下 ...

  6. 谈话准备.xmind 思维导图模版

    谈话准备.xmind 思维导图模版,谈话准备.xmind.zip 谈话准备 目标 1…… 2…… 3…… 影响决定因素 进程 经费 策略 问题 客户 竞争对手 竞争对手 潜在 现存 问题 个性 团队 ...

  7. MySQL性能分析和优化

    1. EXPLAIN 优化你的 SELECT 查询 2. 当只要一行数据时使用 LIMIT 1 3. 为搜索字段建索引 like %最好放右边 4. 尽可能的使用 NOT NULL 5. 在Join表 ...

  8. IDEA上传代码到码云

  9. ACM题目————区间覆盖问题

    题目描述 设x1 , x2,... , xn是实直线上的n个点.用固定长度的闭区间覆盖这n个点,至少需要多少个这样的固定长度闭区间?设计解此问题的有效算法,并证明算法的正确性.编程任务:对于给定的实直 ...

  10. 静态编译C/C++程序

    静态编译C/C++程序,让程序运行不受平台限制 由于Linux操作系统的特有elf加载顺序. (可以参考此文). 虽然可以很大程度上解决Windows早期版本的dll hell问题, 但是给部署带来了 ...