2013 百度校招 研发工程师 一道笔试题

皮特尔 2012-09-24 04:05:45
有20个数组,每个数组里面有500个数组,降序排列,每个数字是32位的unit,求出这10000个数字中最大的500个。

...全文
634 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
皮特尔 2012-10-01
  • 打赏
  • 举报
回复
谢谢各位不吝赐教。
皮特尔 2012-09-28
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 的回复:]

感觉这个就是典型的多路归并啊……
多路归并最常用的办法就是堆和败者树……
代码两天内是写不出来了,要是过两天打算写的话,会把svn发给你的……
[/Quote]
很好,谢谢你了。
子谋 2012-09-28
  • 打赏
  • 举报
回复
感觉这个就是典型的多路归并啊……
多路归并最常用的办法就是堆和败者树……
代码两天内是写不出来了,要是过两天打算写的话,会把svn发给你的……
皮特尔 2012-09-28
  • 打赏
  • 举报
回复
谢谢17楼。
本帖计划两天内结贴。大家谁还有更好的解决办法不妨贡献出来。谢谢大家了。

谁的时间和空间复杂度最低,谁的办法就最好。
huangxy10 2012-09-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
有20个数组,每个数组里面有500个数组,降序排列,每个数字是32位的unit,求出这10000个数字中最大的500个。
[/Quote]

更正一下,添加了注释


#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;

#define ROWS 20
#define COLS 500

int data[ROWS][COLS];

void CreateData()
{
for(int i=0; i<ROWS; i++)
{
for(int j=0; j<COLS;j++)
{
data[i][j] = rand(); //生成随机元素
}
}
for( int i=0; i<ROWS; i++)
sort(data[i],data[i]+COLS, greater<int>()); //对每一行降序排列
}

struct Node
{
int *p; //指向某个列,因为要放入优先队列中,所以要比较大小,就用结构体封装了下
bool operator<(const struct Node &node) const
{
return *p < *node.p;
}
};

void OutMinData( int k)
{
struct Node arr[ROWS];
for(int i=0; i<ROWS;i++)
{
arr[i].p = data[i]; //初始化指针指向各行的首位
}
priority_queue<Node > queue( arr, arr+ROWS ); //使用优先队列,默认是大堆

for( int i=0; i<k&&i<COLS; i++) //算法核心就是这个循环
{
Node temp = queue.top(); //取出队列中最大的元素
cout << *temp.p << " " <<endl;
queue.pop(); //从队列里删除
temp.p++; //对应行的指针后移
queue.push( temp ); //这里面有log(ROWS)次操作,所以算法的总复杂度为O(klog(20))
}

}

int main()
{
CreateData(); //生成数据
int k=500;
OutMinData( k ); //输出k个元素,这里k不要大于列数COL,可以改进,去掉这个限制,不过会让程序不好懂,就没加
}


huangxy10 2012-09-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

没人贴代码吗?再顶一次。
[/Quote]

我先来一个,时间复杂度是O(klog(20))



#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;

#define ROWS 20
#define COLS 500

int data[ROWS][COLS];

void CreateData()
{
for(int i=0; i<ROWS; i++)
{
for(int j=0; j<COLS;j++)
{
data[i][j] = rand();
}
}
for( int i=0; i<ROWS; i++)
sort(data[i],data[i]+COLS, greater<int>()); //降序排列
}

struct Node
{
int *p;
bool operator<(const struct Node &node) const
{
return *p < *node.p;
}
};

void OutMaxData( int k)
{
struct Node arr[ROWS];
for(int i=0; i<ROWS;i++)
{
arr[i].p = data[i]; //初始化指针指向各行的首位
}
priority_queue<Node > queue( arr, arr+ROWS ); //使用优先队列,默认是大堆

for( int i=0; i<k&&i<COLS; i++)
{
Node temp = queue.top();
cout << *temp.p << " " <<endl;
queue.pop();
temp.p++;
queue.push( temp ); //这里面有log(COLS)次操作,所以算法的总复杂度为O(klog(20))
}

}

int main()
{
CreateData(); //生成数据
int k=500;
OutMaxData( k );
}

peng_weida 2012-09-28
  • 打赏
  • 举报
回复
刚打错了,每个数组取前25个数,我晕哟
[Quote=引用 15 楼 的回复:]
1.每个数组取前20个数,共计500个出来建小顶堆
2.从第1个数组第26个元素开始,取出来和堆顶元素做比较
(1)若其小于堆顶元素,则遍历下一个数组第26个元素
(2)若其大于堆顶元素,则更新堆顶元素,并调整堆;然后取第27个元素和堆顶元素比较,做类似处理;

当时是这么做的,不知道得分没有
[/Quote]
peng_weida 2012-09-28
  • 打赏
  • 举报
回复
1.每个数组取前20个数,共计500个出来建小顶堆
2.从第1个数组第26个元素开始,取出来和堆顶元素做比较
(1)若其小于堆顶元素,则遍历下一个数组第26个元素
(2)若其大于堆顶元素,则更新堆顶元素,并调整堆;然后取第27个元素和堆顶元素比较,做类似处理;

当时是这么做的,不知道得分没有

huangxy10 2012-09-28
  • 打赏
  • 举报
回复
时间复杂度可以与n(总共有多少个数无关),只与K(要找的数个数)和数组序列个数M有关。
我能想到的最好的是KlogM。
Gloveing 2012-09-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
引用楼主 的回复:
有20个数组,每个数组里面有500个数组,降序排列,每个数字是32位的unit,求出这10000个数字中最大的500个。

楼主说个题目都说不清?
每个数组里面有500个数组?500个数字吧?
[/Quote]
快速排序、堆排序都比较快
因为这里数不是很多很多,最快的当然是:基数排序
dpdp_2012 2012-09-28
  • 打赏
  • 举报
回复
才10000个数字怎么搞都可以啊。

如果要时间比较优,可以用最大堆,时间复杂度k*logn 空间复杂度n
如果要空间比较优,可以用最小堆,时间复杂度n*logk 空间复杂度k

可以用快排变种
LinuxMan 2012-09-28
  • 打赏
  • 举报
回复
楼主应该是这个意思


[Quote=引用 10 楼 的回复:]

引用楼主 的回复:
有20个数组,每个数组里面有500个数组,降序排列,每个数字是32位的unit,求出这10000个数字中最大的500个。

楼主说个题目都说不清?
每个数组里面有500个数组?500个数字吧?
[/Quote]
Gloveing 2012-09-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
有20个数组,每个数组里面有500个数组,降序排列,每个数字是32位的unit,求出这10000个数字中最大的500个。
[/Quote]
楼主说个题目都说不清?
每个数组里面有500个数组?500个数字吧?
皮特尔 2012-09-28
  • 打赏
  • 举报
回复
这道题要求最小的时间和空间复杂度。
皮特尔 2012-09-25
  • 打赏
  • 举报
回复
没人贴代码吗?再顶一次。
zjwzcnjsy 2012-09-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

1.20个数组最大20放进最大堆中
2.删除最大堆堆顶
3.向最大堆插入在步骤2删除的元素所在数组的下一个元素
4.重复1.2.3
时间复杂度500*log(20)?(不知道对不对?)
[/Quote]
漏了,如果有数组全部已经插入堆中,那么变成了求19个数组中前500-k(步骤2已删除的个数)个最大数了
zjwzcnjsy 2012-09-25
  • 打赏
  • 举报
回复
1.20个数组最大20放进最大堆中
2.删除最大堆堆顶
3.向最大堆插入在步骤2删除的元素所在数组的下一个元素
4.重复1.2.3
时间复杂度500*log(20)?(不知道对不对?)
zjwzcnjsy 2012-09-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

建一个临时的数据结构,在它里面保留最大的500个数。

这个数据结构可最好是一个小顶堆。
枚举所有数组。如果堆中数量小于500,直接插入堆;如果大于500并且准备插入的数组大于堆顶数字,则删除堆顶并将新数字插入堆。

插入堆的过程时间复杂度为log(500),总时间复杂度为 log(500)* N
[/Quote]
插入堆的过程时间复杂度不是log(500)吧,只是删除堆顶是log(500)
Xufukun 2012-09-25
  • 打赏
  • 举报
回复
谁贴点代码出来吧
幽灵娃娃 2012-09-25
  • 打赏
  • 举报
回复
简单么?
加载更多回复(2)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧