基础算法 归并排序 #求逆序对
文章目录
- 题目链接
- 题目解读
- 归并排序
- 如何求逆序对
- 完整代码
- 参考
- 注意
题目链接
题目解读
给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目。
给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目。
输入格式
第一行,一个数 n,表示序列中有 n个数。
第二行 n 个数,表示给定的序列。序列中每个数字不超过 int 所表示的范围。
输出格式
所有逆序对总数。
归并排序
采用分治的思想,将数组递归的分成两半然后进行排序都,最后通过不断合并有序的子数组得到整体有序的数组
归并排序是稳定的排序算法,相同元素的相对位置不会改变
在合并的过程当中,需要使用一个临时数组来存放合并结果,最后还需要将temp复制回原数组的对应位置
如何求逆序对
在合并的过程中可以顺带统计逆序对的数量
完整代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int a[N],temp[N];
int n;
long long ans;
long long mergeSort(int q[],int l,int r){
if(l>=r)return 0;
int mid=(l+r)/2;
ans=mergeSort(q,l,mid)+mergeSort(q,mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid && j<=r){
if(q[i]<=q[j])temp[k++]=q[i++];
else{
ans+=mid-i+1;
temp[k++]=q[j++];
}
}
while(i<=mid)temp[k++]=q[i++];
while(j<=r)temp[k++]=q[j++];
int idx=0;
for(int i=l; i<=r; i++)q[i]=temp[idx++];
return ans;
}
int main(){
cin >> n;
for(int i=0; i<n; i++)cin>>a[i];
mergeSort(a,0,n-1);
cout<<ans;
return 0;
}
参考
acwing 算法平台
注意
🌻编写本篇文章目的是笔者想以输出的形式进行学习,顺便记录学习点滴🌻
🌹 如果本篇文章对你有帮助的话那就点个赞吧👍🌹
😇 本篇文章可能存在多处不足,如有修改意见,可以私信或者评论我哦 😇