求数组最大的前两个数,要求比较次数尽可能少

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求数组最大的前两个数,要求比较次数尽可能少相关的知识,希望对你有一定的参考价值。

参考技术A

此时,最好的情况,即只需要最外面一层比较,即数组是逆序(大->小)的,需要 n 次比较;最坏的情况,即需要两层比较,即数组是顺序的(小->大),需要 2n 次比较;

将数组分为左右两部分,找出左边的最大值和次大值;再找出右边的最大值和次大值;然后把这四个值进行比较;再对左边数组和右边数组递归;
递归基:
因为要取最大值和次大值,因此至少要有2个数;剩下2个数时,取最大值和次大值;剩下3个值时,不能再分为左右两边(一边2个,一边1个,不符合比较),因此三个值也要直接返回,取最大值和次大值;剩下4个值时,可分为左右2个,再往上也都可以合理分为左右2边;

扩展:如何快速求百万级数据的前TopK,待续

分治算法-----二分求最大最小

例题1:给n个实数,求它们之中最大值和最小值,要求比较次数尽量小。

思路:用递归调用函数,在函数里做出以下判断:

1 若left==right(只有一个数) max和min都为这个数

2 若left==right-1(只有两个数) max为较大的,min为较小的

3 除以上两种以外 首先定义中间值d,在递归调用left到d与d+1到right的函数,max为两函数返回值的最大值,min为最小值

核心思路如上

原代码:

#include <iostream>
using namespace std;
int a[132133],maxx,minn;
void qq(int left1,int right1,int &maxx,int &minn)
{
int d=0,max1=0,max2=0,min1=0,min2=0;
if(left1==right1){
maxx=a[left1];
minn=a[left1];
}
if(right1==left1+1){
maxx=max(a[left1],a[right1]);
minn=min(a[left1],a[right1]);
}
else{
d=(left1+right1)/2;
qq(left1,d,max1,min1);
qq(d+1,right1,max2,min2);
maxx=max(max1,max2);
minn=min(min1,min2);
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
qq(1,n,maxx,minn);
cout<<maxx<<" "<<minn;
return 0;
}

错误原因:思路没错,但11行的if前面没有else,导致15行的else只建立在11行的if上,与思路不符,把if前面填个else即可

以上是关于求数组最大的前两个数,要求比较次数尽可能少的主要内容,如果未能解决你的问题,请参考以下文章

把数组中的数拼接起来,求最大值

分治算法-----二分求最大最小

2021-07-30:两个有序数组间相加和的Topk问题。给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组。按照降

求一段C语言程序,主要是比较两个数据组。

返回整数数组最大子数组之和

1159 最大的两个数(指针专题)