数组中的逆序对数量

思路:
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

猜你喜欢

转载自blog.csdn.net/zyd196504/article/details/88321222