找第k大数的时间复杂度

95 views
Skip to first unread message

Tang Qiao

unread,
Jun 30, 2011, 8:29:36 AM6/30/11
to pon...@googlegroups.com
�и������ǣ���һ����������������ҳ���k�����

����������⣬�����öѽ��֮�⣬��һ���ÿ��ŵ�˼��Ľⷨ�����£�

������S�� ����ҳ�һ��Ԫ��X���������Ϊ������Sa��Sb��Sa�е�Ԫ�ش��ڵ���X��Sb��Ԫ��С��X����ʱ�����������
1. Sa
��Ԫ�صĸ���С��k����Sb�еĵ�k-|Sa|��Ԫ�ؼ�Ϊ��k����
2. Sa
��Ԫ�صĸ�����ڵ���k���򷵻�Sa�еĵ�k�� ��

����ݹ���ȥ�����ղ��ð������������Ϳ����ҵ���k����

�����ǣ���μ��������㷨��ƽ��ʱ�临�Ӷȣ��򵥷���һ�£��������2��������partition����ƽ�������Ҫlog(n)�Ρ�

ÿ��partition��Ҫ�ƶ���Ԫ�ظ�����������㣬ƽ���һ����n�����ڶ����� n/2 ����

��ô���ܵ�ƽ��ʱ�临�Ӷ���ô���أ�





Xiang Wang

unread,
Jun 30, 2011, 9:14:41 AM6/30/11
to pon...@googlegroups.com
算法导论上说好像是O(n)

2011/6/30 Tang Qiao <tangq...@gmail.com>
有个问题是:从一个无序的数组里面找出第k大的数。

对于这个问题,除了用堆解决之外,有一种用快排的思想的解法,如下:

从数组S中 随机找出一个元素X,把数组分为两部分SaSbSa中的元素大于等于XSb中元素小于X。这时有两种情况:
1. Sa
中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
2. Sa
中元素的个数大于等于k,则返回Sa中的第k大 数。

这样递归下去,最终不用把整个数组排序就可以找到第k大数。

问题是,如何计算这种算法的平均时间复杂度?简单分析一下,把数组分2部分这种partition操作平均情况下要log(n)次。

每个partition需要移动的元素个数这个不好算,平均第一次是n个,第二次是 n/2 个。

那么,总的平均时间复杂度怎么算呢?








--

Best Regards,

Devil Wang| Engineer of Linux

Gtalk: wxjeacen AT gmail DOT com


窦小蹦

unread,
Jun 30, 2011, 10:00:12 AM6/30/11
to pon...@googlegroups.com
嗯,就是O(N),而且那个证明过特BT。。。
我还写过一个泛型版的linear_selection。但是注意一个限制,原始数据得无重复,否则CLRS上那个算法(LZ的也一样)是得不到正确结果的。

Wu Yin

unread,
Jun 30, 2011, 11:05:06 AM6/30/11
to pon...@googlegroups.com
基本上分三种情况讨论吧, 和randomized quicksort的分析类似, 比较复杂. 结果确实是O(n)
实际上的期望递归次数大概是4 \ln n左右的样子

2011/6/30 Tang Qiao <tangq...@gmail.com>
有个问题是:从一个无序的数组里面找出第k大的数。

对于这个问题,除了用堆解决之外,有一种用快排的思想的解法,如下:

从数组S中 随机找出一个元素X,把数组分为两部分SaSbSa中的元素大于等于XSb中元素小于X。这时有两种情况:
1. Sa
中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
2. Sa
中元素的个数大于等于k,则返回Sa中的第k大 数。

这样递归下去,最终不用把整个数组排序就可以找到第k大数。

问题是,如何计算这种算法的平均时间复杂度?简单分析一下,把数组分2部分这种partition操作平均情况下要log(n)次。

每个partition需要移动的元素个数这个不好算,平均第一次是n个,第二次是 n/2 个。

那么,总的平均时间复杂度怎么算呢?








--
滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。
----------

Xiamen University Cognitive Science Department, Brain-like Intelligent System Labs
Blog (all about mathematics & algorithms): http://wywcgs.wordpress.com
Email: wyw...@gmail.com
Gtalk: wyw...@gmail.com
MSN: wyw...@hotmail.com
QQ: 346693733
TopCoder Handle: wywcgs

Wu Yin

unread,
Jun 30, 2011, 11:14:22 AM6/30/11
to pon...@googlegroups.com
如果原始数据有重复, 你首先要定义你的第k小是个什么概念
CLRS和LZ的算法所说的第k小, 都是指把数据按照非递减排序之后处于第k位的数字

2011/6/30 窦小蹦 <jacklin...@gmail.com>

嗯,就是O(N),而且那个证明过特BT。。。
我还写过一个泛型版的linear_selection。但是注意一个限制,原始数据得无重复,否则CLRS上那个算法(LZ的也一样)是得不到正确结果的。

Xinyu LIU

unread,
Jun 30, 2011, 9:39:36 PM6/30/11
to pon...@googlegroups.com
Hi,

每隔一段时间就有人问K-th selection问题(或曰n-th selection)。
上次是这里:
https://groups.google.com/d/topic/pongba/33UW3x5oKfc/discussion

想严格证明的话,需要用数学希望的知识。上次我给了个不求甚解的解释。
另外在那个thread,我给过另外一个解法:

function nth(xs, k)
  l <- 1
  u <- length xs
  loop
    x <- max(xs[1..k])
    y <- min(xs[k+1..u])
    if x < y then
      return
    else
      swap(x, y)
      l <- partition xs[1..k] with x
      u <- partition xs[k_1..n] with y


2011/6/30 Tang Qiao <tangq...@gmail.com>
有个问题是:从一个无序的数组里面找出第k大的数。

对于这个问题,除了用堆解决之外,有一种用快排的思想的解法,如下:

从数组S中 随机找出一个元素X,把数组分为两部分SaSbSa中的元素大于等于XSb中元素小于X。这时有两种情况:
1. Sa
中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
2. Sa
中元素的个数大于等于k,则返回Sa中的第k大 数。

这样递归下去,最终不用把整个数组排序就可以找到第k大数。

问题是,如何计算这种算法的平均时间复杂度?简单分析一下,把数组分2部分这种partition操作平均情况下要log(n)次。

每个partition需要移动的元素个数这个不好算,平均第一次是n个,第二次是 n/2 个。

那么,总的平均时间复杂度怎么算呢?








--
--
Larry, LIU Xinyu
https://sites.google.com/site/algoxy/
https://github.com/liuxinyu95/AlgoXY

Reply all
Reply to author
Forward
0 new messages