数组总逆序对个数计算


1.逆序对概念

设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同。如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数。


2. 计算数组中逆序对个数


方法一:逐个遍历,复杂度O(n^2)

Java实现如下:

public static int reverseCoupleNum1(char[] str)
	{
		int cnt=0;
		for(int i=0;i<str.length-1;i++)
		{
			for(int j=i+1;j<str.length;j++)
			{
				if(str[i]>str[j]) cnt++;
			}
		}
		
		return cnt;
	}


方法二:利用归并排序中的归并过程对逆序对进行计数,复杂度O(nlgn)

Java实现如下:

public static int mergeSort(char[] str,int p,int q)
	{
		if(p>=q) 
		{
			return 0;
		}
		else
		{
			int cnt1=0,cnt2=0,cnt=0;
			int middle=(p+q)/2;
			cnt1=mergeSort(str,p,middle);
			cnt2=mergeSort(str,middle+1,q);
			
			char[] l=new char[middle-p+1];
			char[] r=new char[q-middle];
			
			System.arraycopy(str, p, l, 0, l.length);
			System.arraycopy(str, middle+1, r, 0, r.length);
			
			//process of merge
			int lpos=0,rpos=0;
			for(int i=p;i<=q;i++)
			{
				if(lpos<l.length&&rpos<r.length)
				{
					if(l[lpos]>r[rpos])
					{
						str[i]=r[rpos++];
						cnt+=l.length-lpos;//KEY POINT
					}
					else
					{
						str[i]=l[lpos++];
					}
				}
				else if(lpos<l.length)
				{
					str[i]=l[lpos++];
				}
				else
				{
					str[i]=r[rpos++];
				}
			}
			return cnt+cnt1+cnt2;
		}
		
		
	}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
树状数组(Fenwick tree)是一种用于高效求解列前缀和(Prefix Sum)问题的据结构,而求逆序对也是一种经典的问题。 假设有个长度为 n 的数组 a,我们要求其逆序对量,即所有 i < j 且 a[i] > a[j] 的 (i,j) 对。这个问题可以用归并排序的思想求解,但是这里我们介绍一种使用树状数组的解法。 思路如下: 1. 将原数组 a 复制一份并排序,得到新数组 b,将 b 的每个元素在原数组 a 的下标记录在数组 c 。 2. 从右往左遍历 a,对于每个元素 a[i],在树状数组查询前缀和 sum(c[i]-1),即小于 a[i] 的元素个数,将结果累加到逆序对器 ans 。 3. 将 a[i] 在数组 c 对应的位置在树状数组更新为 1。 下面是使用 Python 实现的代码: ```python def lowbit(x): return x & -x def update(bit, x, val): n = len(bit) while x <= n: bit[x] += val x += lowbit(x) def query(bit, x): res = 0 while x > 0: res += bit[x] x -= lowbit(x) return res def count_inversions(a): n = len(a) b = sorted(a) c = {v: i+1 for i, v in enumerate(b)} bit = [0] * (n+1) ans = 0 for i in range(n-1, -1, -1): ans += query(bit, c[a[i]]-1) update(bit, c[a[i]], 1) return ans ``` 其,lowbit 函计算 x 的最低位 1 所代表的值;update 函是树状数组的更新操作;query 函是树状数组的查询操作;count_inversions 函是主函,用于计算逆序对量。 时间复杂度为 O(nlogn)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值