剑指offer 数组中的逆序对
问题描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
C++代码实现
思路:1、暴力破解,时间复杂度太大,不能AC
2、归并排序思想
归并排序算法:
// 合并过程
void merge__(vector<int> &arr, int l, int mid, int r) {
// 在这个地方创建额外空间,是一种不好的做法,更好的做法,等下讲
vector<int> tmp(r - l + 1);
int i = l, j = mid + 1, k = 0;
// 两个区间分别从最小值比较
while (i <= mid && j <= r) {
if (arr[i] >= arr[j]) {
tmp[k++] = arr[j++];
}
else {
tmp[k++] = arr[i++];
}
}
while (i <= mid) {
tmp[k++] = arr[i++];
}
while (j <= r) {
tmp[k++] = arr[j++];
}
for (k = 0, i = l; i <= r; ++i, ++k) {
arr[i] = tmp[k];
}
}
// 递归划分过程
void merge_sort__(vector<int> &arr, int l, int r) {
// 只有一个数字,则停止划分
if (l >= r) {
return;
}
int mid = l + ((r - l) >> 1);
merge_sort__(arr, l, mid);
merge_sort__(arr, mid + 1, r);
// 合并两个有序区间
merge__(arr, l, mid, r);
}
// 要排序的数组 arr
void merge_sort(vector<int>& arr) {
merge_sort__(arr, 0, arr.size() - 1);
}
代码如下:
class Solution {
private:
const int kmod = 1000000007;
public:
int InversePairs(vector<int> data) {
int ret = 0;
if (data.size() == 0)
{
return ret;
}
vector<int>temp(data.size());
merge_sort(data, 0, data.size()-1, ret, temp);
return ret;
}
void merge_sort(vector<int> &data, int l, int r, int &ret, vector<int> &temp)
{
if (l >= r)
{
return;
}
int mid = l + ((r - l) >> 1);
merge_sort(data, l, mid, ret, temp);
merge_sort(data, mid + 1, r, ret, temp);
merge(data, l, mid, r, ret, temp);
}
void merge(vector<int> &data, int l, int mid, int r, int &ret, vector<int> &temp)
{
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r)
{
if (data[i] > data[j])
{
temp[k++] = data[j++];
// 出现逆序对情况,累计和
ret += (mid - i + 1);
ret %= kmod;
}
else
{
temp[k++] = data[i++];
}
}
while(i <= mid)
{
temp[k++] = data[i++];
}
while(j <= r)
{
temp[k++] = data[j++];
}
for (i = l, k = 0; i <= r; i++, k++)
{
data[i] = temp[k];
}
}
};
python2代码实现
# -*- coding:utf-8 -*-
class Solution:
def InversePairs(self, data):
# write code here
self.ret = 0
if data == []:
return self.ret
self.temp = [0] * len(data)
self.merge_sort(data, 0, len(data) - 1)
return self.ret
def merge_sort(self, data, l, r):
if l >= r:
return
mid = l + ((r - l) >> 1)
self.merge_sort(data, l, mid)
self.merge_sort(data, mid + 1, r)
self.merge(data, l, mid, r)
def merge(self,data, l, mid, r):
i = l
j = mid + 1
k = 0
while i <= mid and j <= r:
if data[i] > data[j]:
self.temp[k] = data[j]
k += 1
j += 1
self.ret += (mid - i + 1)
self.ret %= 1000000007
else:
self.temp[k] = data[i]
k += 1
i += 1
while i <= mid:
self.temp[k] = data[i]
k += 1
i += 1
while j <= r:
self.temp[k] = data[j]
k += 1
j += 1
i = l
k = 0
while i <= r:
data[i] = self.temp[k]
i += 1
k += 1