您的位置:首页 > 其它

算法入门:最少比较次数求最大/最小/第二大元素

2017-10-15 06:18 861 查看
本文将解决三个问题:

input:A[1……n] 包含n个数字

output:

- A的最大值max

- A的最大值max和最小值min

- A的最大值max和第二大值

要求:比较的次数尽可能少

1.最大元素

如果使用排序的话,常见排序中比较快的有快速排序O(nlogn)。但是显然做一个线性遍历更加快。linear scan的时间复杂度为O(n) 。

max = A[1];
for i=2 to n
if max < A[i]
max = A[i];
return max


2.最大元素和最小元素

值得注意的是这里要求的是比较次数尽可能少,如果做两次linear scan的话是需要2n次比较的,如果使用下面这种方法的话可以将比较次数降低至3/2n。

min = A[1];
max = A[2];
for i = 1 to n
if A[i] < A[i+1]
if max < A[i+1]
max = A[i+1];
if min > A[i]
min = A[i];


对于每一对A[i]和A[i+1],要比较3次,总共有n/2对,所以比较次数是3/2n。

3.求最大元素和第二大元素

如果使用线性扫描的话还是要比较2n次,第一次找最大值,再在剩下的元素中找最大值作为整体的第二大值。这里有一种方法是:在2中假设最大元素为max,将所有与max进行过比较的数字拿出来找最大值,也就是整体的第二大值。

建立一个vector B来存储被击败的数字。它是一个链表,每个元素是一个数组,用来存储当前索引位置的元素击败过的数字,注意是把loser放到B中winner对应的坐标的位置。比如4,2,45,9四个数字,第一次比较2是loser所以把2放进B[1]的位置,1是winner 4的坐标。

这个图会比较清楚:



max(A,i,j)
{
if i = j
return i;
else
mid = ⌊(i+j)/2⌋; // 向下取整
a = max(A,i,mid);// 递归
b = max(A,mid+1,j);
if A[a]>A[b]
insert A[b] into B[a];
return a;
if A[a]<A[b]
insert A[a] into B[b];
return b;
}


最后在主函数中:

main()
{
i = max(A,1,n);
traverse B[i] to find the secondMax;
return A[i],secondMax
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 遍历
相关文章推荐