数组中的逆序对

博客探讨了两种计算数组中逆序对的方法:暴力两层for循环(时间复杂度O(n^2),空间复杂度O(1))和归并排序(时间复杂度O(nlogn),空间复杂度O(n))。通过详细分析归并排序过程,解释了如何确保每次比较和交换操作的正确性,最终得到完整的排序结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.暴力两层for循环,时间复杂度O(n2)O(n^2)O(n2),空间复杂度111.
2.归并排序时间复杂度O(nlogn)O(nlogn)O(nlogn),空间复杂度nnn.

分析:
交换copy和data是因为:
1.在每次的操作中,数值的比较都是采用当前传入函数中第一项,也就是data;比较的结果都存放到copy中;也就意味着此时copy中是经过此次调用的结果。
2.从最底层返回时,进入了(start == end)的情形,data 和 copy 完全没有修改,此时copy和data还是一样的。
3.进入倒数第二层时,程序进入上图26行以后部分,copy是部分排序后的新数组,data是旧数组。注意这里都是传值的调用,数组都是直接修改的。
倒数第二层使用的copy其实是倒数第三层中的data,这就确保了倒数第三层进入26行以后时,数据比较使用的data是最新排序的数组。
4. 倒数第三层将排序的结果存入copy中。程序在倒数第四层进入26行后,使用的data数组为刚刚倒数第三层中的最新排序的copy.
5. 也就是说,在每次程序进入26行时,此时的data是最新的排序结果,copy是次新的结果。
在最后一次进入26行以后时,copy为完整排序后的结果,data是次新的结果。
然而这里第一个类内函数调用第二个函数时,data和copy的顺序没有改变,所以最后结果应该copy是完整排序的结果.data是差一步完成排序的结果。以输入[7,5,6,4], 最后的结果copy[4,5,6,7], data[5,7,4,6].
在这里插入图片描述

在这里插入图片描述

class Solution {
public:
	long long InversePairsCore(vector<int>&data, vector<int>&copy, int low, int high)
	{
		if (low == high)
		{
			copy[low] = data[low];
			return 0;
		}
		int len = (high - low) / 2;
		long long left = InversePairsCore(copy, data, low, low + len);
		long long right = InversePairsCore(copy, data, low + len + 1, high);
		//两指针尾端
		int i =low+len , j = high;
		int indexcopy = high;
		long long count = 0;
		while (i>=low&&j>=low+len+1)
		{
			if (data[i] > data[j])
			{
				copy[indexcopy--] = data[i--];
				count += j - low - len;
			}
			else
			{
				copy[indexcopy--] = data[j--];
			}
		}
		for (; i >= low; i--)
			copy[indexcopy--] = data[i];
		for (; j >= low + len + 1; j--)
			copy[indexcopy--] = data[j];
		return left + right + count;
    }
	int InversePairs(vector<int> data) {
		int len = data.size();
		if (len <= 0)return 0;
		vector<int> copy;
		for (int i = 0; i < len; i++)
			copy.push_back(data[i]);
		long long count = InversePairsCore(data,copy,0,len-1);
		return count % 1000000007;
	}
};

参考剑指offer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值