class Solution {
int cnt = 0;
public int reversePairs(int[] record) {
mergeSort(record, 0, record.length - 1);
return cnt;
}
private void mergeSort(int[] record, int l, int r) {
if (l >= r)
return;
int m = (l + r) / 2;
mergeSort(record, l, m);
mergeSort(record, m + 1, r);
merge(record, l, m, r);
}
public void merge(int[] record, int l, int m, int r) {
int[] tmp = new int[r - l + 1];
int i = l;
int j = m + 1;
int t = 0;
while (i <= m && j <= r) {
if (record[i] <= record[j]) {
tmp[t++] = record[i++];
} else {
cnt += m - i + 1;
tmp[t++] = record[j++];
}
}
while (i <= m) {
tmp[t++] = record[i++];
}
while (j <= r) {
tmp[t++] = record[j++];
}
for (int k = 0; k < tmp.length; k++) {
record[l + k] = tmp[k];
}
}
}
共以下 8 个回答
时间复杂度O(nlogn)
空间复杂度O(n)
解题思路
– 比如数组[9, 7, 5, 4,6],我们在使用归并排序(最终变成升序的过程中)的合并阶段,其实就会去两两比较是否逆序,如果逆序需要交换位置。
– 第一层合并 比如[9]和[7] 就是逆序1个,[5]和[4]就是逆序1个,[6]是逆序0个。(1+1+0=2)
– 第二层合并 [7,9] 和[4,5],7>5,那么7、9(…)都大于4,逆序2个;7>5,那么7、9(…)都大于4,逆序2个 。(2+2=4)
– 第三层合并[4,5,7,9] 和6 ,从7开始,7、9(…)都大于6,逆序2个。(2)
– 总共逆序个数=2+4+2=8个
【题解1】
归并排序
class Solution {
int cnt = 0;
public int reversePairs(int[] record) {
mergeSort(record, 0, record.length-1);
return cnt;
}
}
时间:O(lgn)
空间:O(n)
归并排序,在排序的过程中统计逆序对数量。
时间复杂度O(Nlogn),空间复杂度O(N)。
class Solution {
public int reversePairs(int[] record) {
if (record null || record.length < 2) {
return 0;
}
// 使用归并排序来计算逆序对
return mergeSort(record, 0, record.length – 1);
}
}
思路:归并排序,具体思路参考注释。
时间复杂度:O(nlogn)
空间复杂度:O(n)