思路:
1、由于冒泡排序是对每一次数组遍历中相邻两个存在的逆序对(升序排列时)进行交换,那么完成冒泡排序过程中交换次数就是逆序对存在的个数。
2、利用归并排序的思想[1],将数组递归划分直到只剩各自元素,接下来就是合并过程,由于将数组划分成a[low] - a[mid],a[mid+1] - a[high]两个部分,若前面的某个元素a[i]大于后面的某个元素a[j],那么逆序对个数为 j-(mid+1)+1 = j-mid(首次递归到此处时候只有两个元素,所以相当于前、后均已排好序。更进一步为了维持已经排好序的元素,就要开辟一个新的空间sorted存放排好序的元素),合并的过程中可能出现前或者后其中一个在i、j比较时率先取完,那么还需要对另外一个没有取完的数组(排序好的)继续将其放入到sorted中。利用sorted的原因是防止重复计算逆序对。
实现:
package _数组中逆序对数量;
public class Solution {
public static void main(String[] args) {
int[] a = {364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,
301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,
181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,
221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,
523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,
784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575};
int[] b = {364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,
301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,
181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,
221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,
523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,
784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575};
int count1 = countByBubbleSort(a);
int[] sorted = new int[b.length];
int count2 = countByMergeSort(b, sorted, 0, a.length-1);
System.out.println(count1);
System.out.println(count2);
}
private static int countByMergeSort(int[] a, int[] sorted, int low, int high) {
if(low==high) return 0;
int mid = (low+high) >> 1;
int leftCount = countByMergeSort(a, sorted, low, mid);
int rightCount = countByMergeSort(a, sorted, mid+1, high);
int count = 0;
int sortedFlag = high;
int i=mid, j=high;
while(i>=low&&j>mid) {
if(a[i]>a[j]) {
count += j-mid;
sorted[sortedFlag--] = a[i--];
}
else {
sorted[sortedFlag--] = a[j--];
}
}
for(;i>=low;i--) {
sorted[sortedFlag--] = a[i];
}
for(;j>mid;j--) {
sorted[sortedFlag--] = a[j];
}
for(int k=low;k<=high;k++) {
a[k] = sorted[k];
}
return (leftCount+rightCount+count);
}
private static int countByBubbleSort(int[] a) {
int count = 0;
for(int i=0;i<a.length-1;i++) {
for(int j=0;j<a.length-i-1;j++) {
if(a[j]>a[j+1]) {
swap(a, j, j+1);
count++;
}
}
}
return count;
}
private static void swap(int[] a, int i, int j) {
a[i] = a[i] ^ a[j];
a[j] = a[i] ^ a[j];
a[i] = a[i] ^ a[j];
}
}
1、https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5