求逆序数

29 篇文章 0 订阅
13 篇文章 0 订阅

求逆序数 

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。

现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。比如 1 3 2 的逆序数就是1。

采用分治法+归并排序的思路:左表初始为[l,m]而右表为[m + 1, r],两个表各有一个指针i和j,因此在任意时刻左表为[i,m]而右表为[j, r]。如果右表为空或者两表都不空且a[i]<=a[j]时,元素i从左表中移出;否则元素j从右表中移出,并累加左表元素个数m --j +1。

void sort (int l , int r)
{
	if(l>= r) return 0;
	int m=(l+r)>>1;
	sort(l, m);
	sort(m+1, r);
	// merge [l,m] and [m+1,r]
	int i=l, j=m+1, c=l;
	while (i<=m && j<=r)
	if(j> r || ( i<= m && a[i]<=a[j]) )
	t[c++] = a[i++];
	else
	{ t[c++] = a[j++]; cnt += m-i+1; }
	// copy back
	for(i = l; i<=r; i ++) a[i] = t[i];
}
只要把cnt += m - i + 1;这一句去掉,就是标准的归并排序。时间复杂度也是O(n log n),比普通的O(n^2)算法快很多。需要注意的是附加空间t数组是­O(n)的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值