剑指offer之找出数组中的逆序对

         在数组中的俩个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组的逆序对的总数。

    看到这个问题时,我先想到的方法是遍历整个数组,扫描到一个数字,逐个比较它后面的数字大小。如果后面的数字比它小,则这两个数字就组成一个逆序对,这种方法的是假复杂度是O(N*N),显然,我们必须找到更加高效的算法。

        想想其实可以使用排序来解决这个问题,每次数组里的数据发生一次交换,就说明有一对逆序对,我们可以选择的排序有快速排序和堆排序,这两种排序的时间效率都是比较高的都是O(lgN)。

          但是,还有一中排序和找逆序 对的思想一致,那就是归并排序。归并排序就是把一个数组分成前半段和后半段,然后又拆分前半段为两段,后半段为两段。。。这样拆分下去,最后的子数组长度会为1,开始归并,每一次归并两个数组的时候,如果左数组比右数组大,那么着就是一个逆序。记录所有左数组比右数组大的情况,就是全部的逆序数目。

<pre name="code" class="cpp">int InversePairsCore(int* data, int* copy, int start, int end)
 {
	if (start == end)
        {
		copy[start] = data[start];
		return 0;
	}
	int length = (end-start)/2;
	int left = InversePairsCore(copy, data, start, start+length);
	int right = InversePairsCore(copy, data, start+length+1, end);

	int i = start+length; //前半段最后一个数字的下标
	int j = end;
	int indexCopy = end;
	int count = 0;
	while (i>=start && j>=start+length+1) {
		if (data[i] > data[j]) {
			copy[indexCopy--] = data[i--];
			count += j-start-length;
		} else {
			copy[indexCopy--] = data[j--];
		}
	}
	for (; i>=start; --i)
		copy[indexCopy--] = data[i];
	for (; j>=start+length+1; --j)<pre name="code" class="cpp">		copy[indexCopy--] = data[j];
	return left+right+count;

}

int InversePairs (int* data, int length)
{
	if (data == NULL || length < 0)
		return 0;
	int *copy = new int[length];
	for (int i=0; i<length;++i)
             copy[i]=data[i];
        int count=InversePairCore(data,copy,0,length);
        delete copy;
        return count;
}


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值