我是靠谱客的博主 风趣小熊猫,最近开发中收集的这篇文章主要介绍基础分治-逆序对逆序对,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

逆序对

Description
对于一个序列a,如果有ai > aj且i < j,则称ai, aj为一逆序对。

现给定一个序列,求出序列中逆序对的数量(序列中可能存在重复数字)

Input
第一行是一个整数,表示序列的长度 n。

第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字ai 。

Output
输出一个整数表示答案。

Sample Input
6
5 4 2 6 3 1
Sample Output
11

利用归并排序即可
在这里插入图片描述
如图所示,当a[j]<a[i]时,即 前面所有的元素都和a[j]是逆序对,count +=mid - i + 1;

#include<iostream>

int count = 0;

void mergeAndCount(int * &nums, int left , int mid,int right,int *temp){
	for(int i = left; i <= right; i++){
		temp[i] = nums[i];
	}
	int i = left;
	int j = mid + 1;

	for(int k = left; k <= right; k++){
		if(i == mid + 1){
			nums[k] = temp[j];
			j++; 
		} else if (j == right+1){
			nums[k] = temp[i];
			i++;
		} else if(temp[i] <= temp[j]){
			nums[k] = temp[i];
			i++;
		} else{
			nums[k] = temp[j];
			j++;
			count +=  mid - i + 1;
		}
	}
}
void reversedPairs(int *nums,int left, int right, int *temp){
	if(left == right){
		return ;
	}
	int mid = left+(right-left)/2;
	reversedPairs(nums, left, mid,temp);
	reversedPairs(nums, mid+1,right,temp);	
	mergeAndCount(nums,left,mid,right,temp);
}
 

int main(){
	int n,*arr,*temp;
	scanf("%d",&n);
	arr = new int[n];
	temp = new int[n];
	for(int i = 0 ; i < n; i++){
		scanf("%d",&arr[i]);
	}
	reversedPairs(arr,0,n-1,temp);
	printf("%dn",count);
	return 0;
} 

最后

以上就是风趣小熊猫为你收集整理的基础分治-逆序对逆序对的全部内容,希望文章能够帮你解决基础分治-逆序对逆序对所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部