剑指offer-51

数组中的逆序对

解法一:暴力解法,依次遍历每个值,再计算余下数字与其形成逆序的次数

解法二:仿照归并法。暴力解法在判断某个时,会多次遍历余下节点,仿照归并排序,每次分解依次,在合并的过程中进行计数,从两组待归并的最后一位开始合并,因为已经是排序好的,归并中对前面的数字就不必再比较而直接计算,还是要有图说明比较好

解法一
int InversePairs(int* data, int length) //暴力法
{
	if (data == nullptr || length <= 1) return 0;
	int cnt = 0;
	for (int i=0;i<length;i++)
	{
		for (int j=i+1;j<length;j++)
		{
			if (data[j] < data[i])
				cnt++;
		}
	}
	return cnt;
}

解法二:
int InversePairs(int* data, int start, int end, int* tempArr)//归并法
{
	if (start >= end) return 0;
	int mid = (start + end) >> 1;
	int cnt = 0;
	cnt += InversePairs(data, start, mid, tempArr);
	cnt += InversePairs(data, mid + 1, end, tempArr);
	int* p1 = data + mid;
	int* p2 = data + end;
	int* p3 = tempArr + end;
	while (true)
	{
		if (p1<data+start && p2>data+mid)
		{
			while (p2>data+mid)
			{
				*p3 = *p2;
				p3--;
				p2--;
			}
		}
		else if (p1>=data+start && p2<=data+mid)
		{
			while (p1>=data+start)
			{
				*p3 = *p1;
				p3--;
				p1--;
			}
		}
		else if (p1>=data && p2>data+mid)
		{
			if (*p1>*p2)
			{
				cnt += p2 - (data + mid);
				*p3 = *p1;
				p3--;
				p1--;
			}
			else
			{
				*p3 = *p2;
				p3--;
				p2--;
			}
		}
		else
			break;
	}
	for (int i=start;i<=end;i++)
		data[i] = tempArr[i];
	
	return cnt;
}
int InversePairs_merge(int* data, int length) //归并法
{
	if (data == nullptr || length <= 1) return 0;
	int* tempArr = new int[length]();
	return InversePairs(data, 0, length - 1, tempArr);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值