一种在两个大小为n的数组中找到第n个最大数的算法

时间:2013-01-26 10:12:31

标签: algorithm language-agnostic

我有这个问题:

  

给定大小为n的两个排序列表(存储在数组中),找到一个O(log n)   计算联合中第n个最大元素的算法   两个清单。

我可以看到这里可能有一个技巧,因为它需要第n个最大的元素,并且数组的大小也是n,但我无法弄清楚它是什么。我以为我可以适应计数排序,那会有用吗?

3 个答案:

答案 0 :(得分:7)

比较A [n / 2]和B [n / 2]。如果相等,其中任何一个都是我们的结果。此算法的其他停止条件是两个数组的大小均为1(最初或在几个递归步骤之后)。在这种情况下,我们只选择最大的A [n / 2]和B [n / 2]。

如果A [n / 2]< B [n / 2],递归地重复此过程,用于A []的后半部分和B []的前半部分。

如果A [n / 2]> B [n / 2],递归地重复此过程为B []的后半部分和A []的前半部分。

由于在每一步中问题大小(在最坏的情况下)减半,我们将得到O(log n)算法。


除非n是2的幂,否则始终将数组大小除以2以使索引正常工作。更正确的选择索引的方法(对于任意n)将对一个数组使用相同的策略,但选择补充索引:j=n-i用于其他数组。

答案 1 :(得分:2)

Evgeny Kluev给出了一个更好的答案 - 我的是O(n log n),因为我没想到它们被排序。

我可以添加的内容是为您提供一个非常好的视频链接,解释二进制搜索,麻省理工学院提供:

https://www.youtube.com/watch?v=UNHQ7CRsEtU

答案 2 :(得分:1)

public static void main(String[] args) {  


int[] fred = { 60, 5, 7, 3, 20, 3, 44 };  

int[] tmp = new int[fred.length];  
go(fred, 1, tmp, 3);  
}  

public static void go(int[] fred, int cnt, int[] tmp, int whatPosition) {  
int max = 0;  
int currentPosition = 0;  
for (int i = 0; i < fred.length; i++) {  
if (i == 0)  
max = fred[i];  
else {  
if (fred[i] > max) {  
max = fred[i];  
currentPosition = i;  
}  
}  
}  
System.arraycopy(fred, 0, tmp, 0, fred.length);  
tmp[currentPosition] = 0;  
cnt++;  
if(cnt != whatPosition)  
go(tmp, cnt, tmp, whatPosition);  
else{  
for (int i = 0; i < tmp.length; i++) {  
if (i == 0)  
max = tmp[i];  
else {  
if (tmp[i] > max) {  
max = tmp[i];  
}  
}  
}  
System.out.println(max);  
}  




}