修改合并排序:(已经测试过的代码)
花费O(nlogn) 时间。
public class MergeSort {
static HashMap<Integer, Integer> valueToLowerCount = new HashMap<Integer, Integer>();
public static void main(String[] args) {
int [] arr = new int[] {50, 33, 37, 26, 58, 36, 59};
int [] lowerValuesOnRight = new int[] {4, 1, 2, 0, 1, 0, 0};
HashMap<Integer, Integer> expectedLowerCounts = new HashMap<Integer, Integer>();
idx = 0;
for (int x: arr) {
expectedLowerCounts.put(x, lowerValuesOnRight[idx++]);
}
for (int x : arr) valueToLowerCount.put(x, 0);
mergeSort(arr, 0, arr.length-1);
//Testing
Assert.assertEquals("Count lower values on right side", expectedLowerCounts, valueToLowerCount);
}
public static void mergeSort(int []arr, int l, int r) {
if (r <= l) return;
int mid = (l+r)/2;
mergeSort(arr, l, mid);
mergeSort(arr, mid+1, r);
mergeDecreasingOrder(arr, l, mid, r);
}
public static void mergeDecreasingOrder(int []arr, int l, int lr, int r) {
int []leftArr = Arrays.copyOfRange(arr, l, lr+1);
int []rightArr = Arrays.copyOfRange(arr, lr+1, r+1);
int indexArr = l;
int i = 0, j = 0;
while (i < leftArr.length && j < rightArr.length) {
if (leftArr[i] > rightArr[j]) {
valueToLowerCount.put(leftArr[i], valueToLowerCount.get(leftArr[i]) + rightArr.length - j);
arr[indexArr++] = leftArr[i++];
}else {
arr[indexArr++] = rightArr[j++];
}
}
while (i < leftArr.length) {
arr[indexArr++] = leftArr[i++];
}
while (j < rightArr.length) {
arr[indexArr++] = rightArr[j++];
}
}
}
要查找右侧大于数组元素的值的总数,只需更改单行代码:
if (leftArr[i] > rightArr[j])
到
if (leftArr[i] < rightArr[j])