IBM面试题:n个无序整数,求第K大或者前K大的数(不要求排序输出,找到就行)

RobertC 2012-11-09 09:14:01
n个无序整数,求第K大或者前K大的数(不要求排序输出,找到就行),时间复杂度为O(n),各位有什么好的想法吗?

进一步如果要求排序输出的话,最好的时间复杂性是多少?
...全文
6466 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuangge603 2012-12-27
  • 打赏
  • 举报
回复
编程之美 ok
prototyper 2012-12-26
  • 打赏
  • 举报
回复
<script type=text/javascript> // 生成100000个无序整数arr,连续和不重复是为了生成和验证结果的方便,不连续和有重复也行。 var n = 100000, arr = []; while (n --) { arr.push(n + 1); } arr.sort(function(){return Math.random() > 0.6}); // 仅知arr为无序整数集合,查找其中第5(这里设k为5)大的数和前5大数 var t = new Date(); var i = arr.length, j = 0, k = 5, bit = [], jsout = []; while (i --) { bit[arr[i] >> 5] |= (1 << (arr[i] & 0x1f)); } j = bit.length * 32; // 64位系统j = bit.length * 64 while (jsout.length < k && j --) { bit[j >> 5] & (1 << (j & 0x1f)) && jsout.push(j); } t = new Date() - t; document.write("前5大数为:" + jsout.join(" 和 ") + "<br/>"); document.write("第5大数为:" + jsout.pop() + "<br/>"); document.write("查找时间:" + t + "毫秒"); </script>
prototyper 2012-12-25
  • 打赏
  • 举报
回复
上面的"arr"就题目中给定的n个无序整数集合数组
prototyper 2012-12-25
  • 打赏
  • 举报
回复
再给个js的。 var k, n, bit = [], jsout = []; while (-- n) { bit[arr[n] >> 5] |= (1 << (arr[n] & 0x1f)); } var j = (bit.length - 1) * 32 // 64位系统 * 64; while (jsout.length < k && j --) { bit[j >> 5] & (1 << (j & 0x1f)) && jsout.push(j); } 第k大的数为jsout[0] 前k大的数排序输出为jsout.join("和")
超级大笨狼 2012-12-25
  • 打赏
  • 举报
回复
思路2,快排的原理 随便找一张牌 M个比我大,N-M个比我小 丢弃这两堆里,比K小的一半,不考虑。 重复这个过程,直到M=K结束 复杂度是N*lgK=N 快排没有丢弃的过程,所以复杂度是N*LgN
cfvmario 2012-12-25
  • 打赏
  • 举报
回复
说实话,1楼那个书上的算法,当初学的时候就感觉实用性恐怕不行,太麻烦,常数因子估计了一下不小 还不如直接用和快排差不多的代码,只不过一轮以后就知道第K个元素在哪一半里,下一趟只处理那一半就行了,思路和实现简单 额,应该就是3楼那个吧
超级大笨狼 2012-12-25
  • 打赏
  • 举报
回复
原理:满二叉树可以用数组构建 假设前K大在数组的前端 根节点在k/2处 第二层,在距离根k/4的两侧 第三层,在距离第二层k/8处 依次类推 用这个假设的二叉树作为栈 扫描数组元素,检查其和栈内节点的大小 该上升的上升,该下降的下降 从栈底挤出最小的 消耗复杂度是Lg(K) * N K<N/2 是常数
heartlc 2012-12-23
  • 打赏
  • 举报
回复
是不是用类似快排的方法?
hua_zhixing_ 2012-12-21
  • 打赏
  • 举报
回复
Top K 算法,找度娘或谷哥吧?
蜡笔小新啦 2012-12-21
  • 打赏
  • 举报
回复
算法导论中有,快排的变种。
nice_cxf 2012-12-19
  • 打赏
  • 举报
回复
编程之美上边的题目把,最大堆排序
skillart 2012-12-19
  • 打赏
  • 举报
回复
选择前K个元素,每次和这K个数中最小的数比较,若大于则交换。重复此步骤,遍历一遍。 第二问:上面那个快排的思想+1
白米若雪 2012-11-11
  • 打赏
  • 举报
回复
great!!!
引用 1 楼 icessl 的回复:
就是"线性时间选择"算法,该算法如下: STEP1. if (n<75) 排序后取第 k 个数; // 该步耗时 O(1) STEP2. 将输入的序列分成 g=n/5 个组,将每组的中位数存入数组 B; // 该步耗时 O(n) STEP3. 递归地,求 B 的中位数 X; // 该步耗时 T(n/5) STEP4. 把输入序列中小于 X 的放入……
b123456_89 2012-11-10
  • 打赏
  • 举报
回复
3L正解、。。。。(最少输入6字符。。。。。)
icessl 2012-11-10
  • 打赏
  • 举报
回复
如果先排序再输出,时间耗费 T(n)=O(nlogn)
icessl 2012-11-10
  • 打赏
  • 举报
回复
就是"线性时间选择"算法,该算法如下: STEP1. if (n<75) 排序后取第 k 个数; // 该步耗时 O(1) STEP2. 将输入的序列分成 g=n/5 个组,将每组的中位数存入数组 B; // 该步耗时 O(n) STEP3. 递归地,求 B 的中位数 X; // 该步耗时 T(n/5) STEP4. 把输入序列中小于 X 的放入集合C,大于等于 X 的放入集合 D; STEP5. if (k<=|C|) 递归地在 C 中找第 k 个元; else 递归地在 D 中找第 k-|C| 小元; // 该步耗时 T(0.75n) 总时间耗费 T(n)=T(0.2n)+T(0.75n)+O(n)=O(n)
prototyper 2012-11-10
  • 打赏
  • 举报
回复
如果JS的话,我会尽量使用原生算法:

Array.prototype.getElementMax = function(k) {
    var i = 0, arr = this, M = Math.max.apply(Math, arr);
    arr.join(",").replace(/[^,]+/g, function($){if($ == M){arr[i] = 0; return} i++});
    return k ? [M].concat(arr.getElementMax(--k)) : [];
}

var arr = [], obj = {};
while (arr.length < 1000) {
    var num = Math.random() * 10000 >> 0;
    obj[num] || (arr.push(num), obj[num] = true);
}
alert(arr.getElementMax(3).pop()); //第3(k)大整数
//alert(arr.getElementMax(3));     //前3(k)大整数
icessl 2012-11-10
  • 打赏
  • 举报
回复
to 4 楼:if (n<75) 排序后取第 k 个数; 为什么排序耗时是1 // 该步耗时 O(1) 答:因为元素个数是常数,耗时也是常数,所以是 O(1)
zhaoyjrf 2012-11-10
  • 打赏
  • 举报
回复
用归并树或者划分树就可以,建树O(n),查找O(logn)
tkminigame 2012-11-10
  • 打赏
  • 举报
回复
建立一个有序列,长度为k,二分插入,打印出来的第一个为第k大,复杂度O(n)
def find(a,k):
    result = sorted(a[0:k])
    for x in a[k:]:
        if x>result[0]:
            result.pop(0)
            #bi sect search
            lo = 0
            hi = k-1
            while lo<hi:
                mid = (lo+hi)//2
                if x>result[mid]:
                    lo = mid+1              
                else:
                    hi = mid
            result.insert(lo, x)
            
    print(result)

find([3,4,5,2,1,3,4,5,6],3)
加载更多回复(2)

33,009

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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