分而治之
求逆序数
void Merge(string a,int low,int mid,int high){
//参考合并两个链表的时候的做法
int tmpa[high-low+1];
int ans=0;
int i=low,j=mid+1,k=0;//i,j分别是指向两个数列对应的位置的,k是指向最终的数列中位置的坐标
while(i<=mid&&j<=high){
if(a[i]<=a[j]){
tmpa[k++]=a[i++];
}
else{
tmpa[k++]=a[j++];
ans+=(mid-i+1);
}
}
if(i<=mid){
while(i<=mid)
tmpa[k++]=a[i++];
}
if(j<=high){
while(j<=high)
tmpa[k++]=a[j++];
}
for(int i=low;i<=high;i++)
a[i]=tmpa[i-low];
}
void MergeSort(string a,int low,int high){
int mid;
if(low<high){
mid=(low+high)/2;
MergeSort(a, low, mid);//对于前半个排序
MergeSort(a, mid+1, high);//对于后面半个排序
Merge(a, low, mid,high);//合并
}
}
求最大元素和次大元素
- 如果只有一个元素,那么一个最大,另外一个设为负无穷
- 如果有两个元素,一个是最大,一个是次大
- 如果有多于两个元素,那么最大的是左右两边当中最大的那一个,次大的是
void Solve(int a[],int low,int high,int &max1,int &max2){
if(low==high){
max1=a[low];
max2=-100000;
}
else if(low==high-1){
max1=a[low]>a[high]?a[low]:a[high];
max2=a[low]+a[high]-max1;
}
else {
int mid=(low+high)/2;
int lmax1,lmax2;
solve(a,low,mid,lmax,lmin);
int rmax1,rmax2;
solve(a,mid+1,high,rmax,rmin);
max1=lmax1>rmax1?lmax1:rmax1;
if(max1==lmax1){
max2=lmax2>rmax1?lmax2:rmax1;
}
else{
max2=rmax2>lmax1?rmax2:lmax1;
}
}
}
查找序列中第k小的元素
借助快速排序的思想
借用第一个作为枢轴,对于数列进行划分,如果一次划分之后书作的位置i=k-1,那么在这个时候恰好是第k 个元素。
如果k-1<i,那么第k小的元素在前面,那么对于前面的元素进行划分
如果k-1>i,那么第k小的元素应该在后面,如果不是,那么再对于后