在线求n个数中第k大的,可否直接调用STL?

cotton201012 2012-02-07 10:31:01
给定n个数,会动态的增加、删除、更改某个元素。也会随时询问当前第k大的数(每次的k不相等)。要求时间复杂度均为O(lg n)
一直想用set,但不知道怎么能做到。问了别人,有人让我手写set。实在是懒啊。。。STL真的没有解决方案吗?
...全文
667 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
cotton201012 2012-02-09
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 heartszhang 的回复:]

stl里指定没有,我说的二叉树方法可以用,自己实现一个也花不了1天,你这都耽搁了好几天了。
[/Quote]

我并不是急于解决这个问题。我早晚要解决手写平衡树的问题,只是想了解一下,什么情况需要手写。

还是感谢楼上各位朋友的帮助。努力学习红黑树了
warren258 2012-02-09
  • 打赏
  • 举报
回复
第k序位数请参考TAOCP
heartszhang 2012-02-09
  • 打赏
  • 举报
回复
stl里指定没有,我说的二叉树方法可以用,自己实现一个也花不了1天,你这都耽搁了好几天了。
cotton201012 2012-02-09
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fetag 的回复:]

两种方法,效率不同,先说低的

1)先来个排序,随便哪种都行,heap sort,quick sort or merge sort,开销是n*log(n),然后直

接取第k个元素就行了。

2)第二种是用分治法解决,类似于像随机快速排序里面的思想,开销O(n)。假如有1到n个数字,先任意选

择一个主元,将数列分成两个部分,假设主元的下标是p,所有小于主元的放在左侧,大于主元的……
[/Quote]
O(n)的线性算法我用过。但对于大量的询问,每次O(n)的代价太大了。
cotton201012 2012-02-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 mingliang1212 的回复:]

最懒的做法是两个优先队列,一个保存K个数,另一个保存n-k。如果你足够聪明,应该懂我说什么了。手机打字少。
[/Quote]
你的意思我明白。我做过。但这么做要求k存在单调性。但这里的k是随机变化的。用两个堆就做不到了吧
Furney 2012-02-08
  • 打赏
  • 举报
回复
算法导论快速排序里面有讲解,楼主可以去看下。
卡卡_苏米 2012-02-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fetag 的回复:]
两种方法,效率不同,先说低的

1)先来个排序,随便哪种都行,heap sort,quick sort or merge sort,开销是n*log(n),然后直

接取第k个元素就行了。

2)第二种是用分治法解决,类似于像随机快速排序里面的思想,开销O(n)。假如有1到n个数字,先任意选

择一个主元,将数列分成两个部分,假设主元的下标是p,所有小于主元的放在左侧,大于主元的放……
[/Quote]

这个很好 哈哈 感觉第二种很易懂啊 跟快速排序的思想有些类似 但是它因为不需要排序,所以找第K个大的数时节约了大量时间
heartszhang 2012-02-08
  • 打赏
  • 举报
回复
我想了一下,我说的方法,

建立树 O(nlg n)
其他都是O(lg n)
可以用红黑树等复杂的树实现,必要时旋转一下。旋转的时候count处理要处理好。。
heartszhang 2012-02-08
  • 打赏
  • 举报
回复
我没具体分析,但是插入和寻找应该是o(lgn)
删除也应该是o(lg n)你可以分析一下。
seucs 2012-02-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 cxsjabcabc 的回复:]
n个数直接堆存储,堆排序
[/Quote]

时间复杂度变为 O(klog n),不符合楼主要求

如果只是在n个元素中找第k大的数,线性选择时间复杂度可以达到 O(n),也比楼主所要求的 O(lg n)大
heartszhang 2012-02-08
  • 打赏
  • 举报
回复
楼主。。可以用binary tree来实现。

每一个node里面添加2个数据:int left_count; int right_count;记录多少个node在这个node左边,和多少个node在这个node右边。

就可以log(n)的找到kth element。
seucs 2012-02-08
  • 打赏
  • 举报
回复
给定n个数,会动态的增加、删除、更改某个元素。也会随时询问当前第k大的数(每次的k不相等)。要求时间复杂度均为O(lg n)
答:鱼和熊掌不可兼得,想要时间复杂度均为O(lg n),这个要求达不到。
一、如增加时要保证有序的话:
1、如果用数组存储,插入一个元素的时间复杂度最坏情况下为O(n),但查找时时间复杂度可达到O(1);
2、如果用链表存储,那么插入一个元素时间复杂度为O(n),查找时时间复杂度为O(n);
二、如果增加时元素无序,那么查询第k大的元素的最优复杂度是线性的,即需要O(n)

综上,你的要求满足不了
程序员小迷 2012-02-08
  • 打赏
  • 举报
回复
n个数直接堆存储,堆排序
taodm 2012-02-08
  • 打赏
  • 举报
回复
stl里现成的,就不要折腾了。
Wolf0403 2012-02-08
  • 打赏
  • 举报
回复
第二种不就是手写 qsort,只不过只排序相关的一半么……
qq120848369 2012-02-08
  • 打赏
  • 举报
回复
没有lgn找第n大的算法。
独孤过儿 2012-02-08
  • 打赏
  • 举报
回复
两种方法,效率不同,先说低的

1)先来个排序,随便哪种都行,heap sort,quick sort or merge sort,开销是n*log(n),然后直

接取第k个元素就行了。

2)第二种是用分治法解决,类似于像随机快速排序里面的思想,开销O(n)。假如有1到n个数字,先任意选

择一个主元,将数列分成两个部分,假设主元的下标是p,所有小于主元的放在左侧,大于主元的放在右侧。

这一遍跑完了,n个数就分成了三组:(1,p-1),p,(p+1,n),最左面的部分是小于主元的,中间是主元(可

能有多个和主元相等的值),右侧是大于主元的。然后开始看三部分的长度,和要找的k比较,就知道要找的

那个元素会落在哪个区域里面了。然后继续用新的下标递归。

我的描述可能看不懂,具体的可以参阅《算法导论》第三版的9.2 Selection in expected linear time.
iamnobody 2012-02-07
  • 打赏
  • 举报
回复
最懒的做法是两个优先队列,一个保存K个数,另一个保存n-k。如果你足够聪明,应该懂我说什么了。手机打字少。
cotton201012 2012-02-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mstlq 的回复:]

不好意思,贴错了,楼主试试nth_element吧
[/Quote]
nth_element 每次都能到O(lg n)?应该是每次O(n)吧。而且参数是RandomAccessIterator, set没有。
mstlq 2012-02-07
  • 打赏
  • 举报
回复
不好意思,贴错了,楼主试试nth_element吧
加载更多回复(2)

64,646

社区成员

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

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