分治思想的应用
题目一:
在 n 个元素中找出最大元素和最小元素:
我们先使用朴素算法:
#include<iostream>
using namespace std;
#define MAXSIZE 200
int main()
{
int a[MAXSIZE],n,num;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>num;
a[i] = num;
}
int max,min;
max = min = a[0];
for(int j=1;j<n;j++)
{
max = a[j]>max?a[j]:max;
min = a[j]>min?min:a[j];
}
cout<<max<<" "<<min;
return 0;
}
在获得最大最小值时对于n个数我们需要比较2(n-1)次 ,也就是说时间复杂度为2(n-1)
接下来我们用分治策略来处理这道题
T(n) = 2T(n/2) + Θ(1) n>1
T(n) = Θ(1) N=1
对于这n个数,我们分为两组,分别求出每一组的最大值和最小值,再比较这两组的最大值与最小值,使用递归即可简单的解决问题
直接上代码:
#include<iostream>
#define MAXSIZE 200
#define MAX(a,b) a>b?a:b;
#define MIN(a,b) a>b?b:a;
using namespace std;
void Max_Min(int i,int j,int &max,int &min,int a[])
{
if(j-i==1)//递归的截至条件1(当n为偶数时)
{
if(a[j]>a[i])
{
max=a[j];
min=a[i];
}
else
{
max=a[i];
min=a[j];
}
}
else if(j==i)//递归的截止条件2(当n为奇数时)
{
max=min=a[i];
}
else
{
int max1,max2,min1,min2;
int mid = (i+j)/2;
Max_Min(i,mid,max1,min1,a);//递归调用
Max_Min(mid+1,j,max2,min2,a);//递归调用
max=MAX(max1,max2);//获取每一步的最大值
min=MIN(min1,min2);//获取每一步的最小值
}
}
int main()
{
int a[MAXSIZE],n,num;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>num;
a[i] = num;
}
int max,min;
Max_Min(0,n-1,max,min,a);
cout<<max<<" "<<min;
return 0;
}