题解 | #数组中的逆序对#
数组中的逆序对
https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 这是二路归并排序的算法题,重点是需要一个辅助的数组,将原来的数据存放到辅助的数组
一旦存放到辅助数组上,再下一轮的合并中,原始数据的位置就会成为目的地址,或者将上一轮的两个有序
子序列的内容,先放到原始数组中,合并时再放到dst数组中,这样保存了dst的属性在整个算法的含义一致性,
但也由此消耗了一些性能;
*
* @param nums int整型vector
* @return int整型
*/
int InversePairs(vector<int>& nums) {
if (nums.empty() || nums.size() == 1)
return 0;
std::vector<int> dst(nums.size(), -1);
return InversePairs(nums, dst, 0, nums.size()-1);
}
int InversePairs(vector<int>& nums, vector<int>& dst, int left, int right) {
if (left >= right) {
dst[left] = nums[left];
return 0;
}
auto mid = left + ((right - left) >> 1);
auto ret = InversePairs(nums, dst, left, mid) + InversePairs(nums, dst, mid+1, right);
ret %= mod_;
// InversePairs返回的结果放在dst中,而nums中的数据已不需要了。
// 这个时候,为了保证合并之后的正确的序列仍然放在dst中,可以将nums和dst子left和right之间的数据进行交换;
for (int i = left; i <= right; ++i) {
nums[i] = dst[i];
}
auto i = mid, j = right;
auto k = right;
auto count = 0;
while (i >= left && j >= mid+1) {
if (nums[i] > nums[j]) {
count += j - mid; // 累加逆序对个数
dst[k--] = nums[i--]; // 排序,将当前最大放入到dst中
} else {
dst[k--] = nums[j--]; // 排序,将当前最大放入到dst中
}
}
while (i >= left) // 如果右边的数组已无数据,就需要将左边的数据放入dst数组中
dst[k--] = nums[i--];
while (j >= mid+1)// 如果左边的数组已无数据,就需要将右边的数据放入到dst数组中
dst[k--] = nums[j--];
return (ret + count) % mod_;
}
private:
int mod_ {1000000007};
};
莉莉丝游戏公司福利 699人发布