對於一個包含N個非負整數的陣列A[0..n-1],如果有0<=i < j<n,且A[ i ]>A[ j ],則稱(A[ i] ,A[ j] )為陣列A中的一個逆序對。
現給定一組數,請你算出這組數中共有多少組逆序對。
輸入格式:
共兩行,第一行是一個整數N(N≤1000),表示這組數的個數。第二行有N個整數,用空格分隔,為這組數。測試用例保證合法且所有數均可以用int儲存。
輸出格式:
只有一行,為一個整數,代表這組數中逆序對的數量。
輸入樣例:
5
3 1 4 5 2
輸出樣例:
4
分析:
1、樸素解法:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner sc = new Scanner(System.in); 6 int n = sc.nextInt(); 7 int[] array = new int[n]; 8 for (int i = 0; i < n; i++) { 9 array[i] = sc.nextInt(); 10 } 11 12 int count = 0; 13 14 for (int i = 0; i < n; i++) { 15 for (int j = i + 1; j < n; j++) { 16 if (array[i] > array[j]) { 17 count++; 18 } 19 } 20 } 21 22 System.out.println(count); 23 24 sc.close(); 25 } 26 }
時間複雜度O(n2)
2、歸併排序
1 import java.util.Scanner; 2 3 public class nixu { 4 public static void main(String[] args) { 5 Scanner scanner = new Scanner(System.in); 6 int n = scanner.nextInt(); 7 int[] numbs = new int[n]; 8 for (int i = 0; i < n; i++) { 9 numbs[i] = scanner.nextInt(); 10 } 11 System.out.println(countInversions(numbs)); 12 } 13 14 public static int countInversions(int[] numbs) { 15 return mergeSort(numbs, 0, numbs.length - 1); 16 } 17 18 private static int mergeSort(int[] nums, int left, int right) { 19 if (left >= right) return 0; 20 int mid = left + (right - left) / 2; 21 int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); 22 int[] temp = new int[right - left + 1]; 23 int i = left, j = mid + 1, k = 0; 24 while (i <= mid && j <= right) { 25 if (nums[i] <= nums[j]) { 26 temp[k++] = nums[i++]; 27 } else { 28 temp[k++] = nums[j++]; 29 count += mid - i + 1; 30 } 31 } 32 while (i <= mid) temp[k++] = nums[i++]; 33 while (j <= right) temp[k++] = nums[j++]; 34 System.arraycopy(temp, 0, nums, left, temp.length); 35 return count; 36 } 37 }
時間複雜度O(nlogn)