算法引入:
对一个数组的基本考法:
1.排序(卡时间复杂度)
2.查找(卡时间复杂度)
使用sort函数进行排序:
一般的不卡时间复杂度的问题使用sort函数进行排序,已经足够了。所以sort函数的用法:
sort(数组名,数组大小,排序方法);
例:
(1)a[],下标为0~N-1,则sort(a,a+n);//方法不填默认为递增
(2)a[],下标为1~N,则sort(a+1,a+n+1);
排序方法:我熟练写bool函数进行:
bool cmp(int x,int y){
return x > y; //降序
//return x < y;//升序
}
写法:sort(a,a+n,cmp);
时间复杂度:O(n2);
所以就出现了一系列优化的方法:
归并排序:
归并排序是利用递归的方法进行排序,将一个数组不断分割除二,然后再递归,将时间复杂度优化成nO(lng2n)的方法,如图:
每排的复杂度为O(n),然后有log2n排。
归并算法的思想:分治
算法步骤:
1.[L,R] => [L,mid]+[mid+1,R];
2.递归排序[L,mid]和[mid+1,R];
3.归并,将左右两个有序序列合并成一个有序序列
void ksort(int q[],int l,int r){
if(l>=r) return;
int mid=(l+r)>>1;
ksort(q,l,mid),ksort(q,mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r){
if(q[i]<=q[j]) tmp[k++]=q[i++];
else tmp[k++]=q[j++];
}
while(i<=mid) tmp[k++]=q[i++];
while(j<=r) tmp[k++]=q[j++];
for(int i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
}
vector二分排序插入
归并排序算是基本第一个优化,而二分插入排序的时间复杂度是O(n2);但是在vector中封装的方法却可以很快,所以可以这样优化
例:
洛谷的一题中位数,如果直接用sort排序是肯定过不去的,所以我想到了归并优化发现时间复杂度还是超了,最后看题解发现vector更好更方便,如图分别是sort,归并,还有vector的时间复杂,可以明显看出有优化在里面的。
本题用到了vector函数中的upper_bound方法,进行二分排序并插入,进行时间复杂度的优化。
#include<bits/stdc++.h>
using namespace std;
//#define int long long
const int N = 1e6 + 10;
vector<int> v;
signed main() {
int n;
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
v.insert(upper_bound(v.begin(),v.end(),x),x);
if(i%2==1){
cout<<v[(i-1)/2]<<endl;
}
}
return 0;
}