陣列中的逆序對

Joy_917發表於2020-12-30

題目:

在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個陣列,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007
輸入描述:
題目保證輸入的陣列中沒有的相同的數字
示例1
輸入:[1,2,3,4,5,6,7,0]
返回值:7

思路:

  1. 開始用了暴力法,兩層迴圈兩兩比對,果然超時了
  2. 檢視題解,思路和快排思想十分類似,本質是分治然後歸併
  3. 簡單來說,就是把大陣列M切分成一個個小陣列比如A、B,組內比較計數然後排序;如果A的最小值都大於B的最大值,說明無論AB各自的元素如何排列,都不存在符合條件的逆序對,這時候將AB合併,和其他的小陣列進行比較
  4. 還是有點繞的,這裡先記一下

程式碼(歸併法):

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        str = str.substring(1, str.length()-1);
        String[] valueArr = str.split(",");
        int[] array = new int[valueArr.length];
        for (int i = 0; i < valueArr.length; i++) {
            array[i] = Integer.parseInt(valueArr[i]);
        }
        System.out.println(InversePairs(array));
    }
    public static int InversePairs(int [] array) {
        if(array == null) return 0;
        int[] tmp = new int[array.length];
        return mergeSort(array, tmp, 0, array.length-1);
    }
    //歸併排序,遞迴
    private static int mergeSort(int[] array, int[] tmp, int low, int high) {
        if(low >= high) return 0;
        int res = 0, mid = low + (high - low) / 2;
        res += mergeSort(array, tmp, low, mid);
        res %= 1000000007;
        res += mergeSort(array, tmp, mid + 1, high);
        res %= 1000000007;
        res += merge(array, tmp, low, mid, high);
        res %= 1000000007;
        return res;
    }
    //歸併排序,合併
    private static int merge(int[] array, int[] tmp, int low, int mid, int high) {
        int i1 = low, i2 = mid + 1,k = low;
        int res = 0;
        while(i1 <= mid && i2 <= high) {
            if(array[i1] > array[i2]) {
                res += mid - i1 + 1;
                res %= 1000000007;
                tmp[k++] = array[i2++];
            } else
                tmp[k++] = array[i1++];
        }
        while(i1 <= mid)
            tmp[k++] = array[i1++];
        while(i2 <= high)
            tmp[k++] = array[i2++];
        for (int i = low; i <= high; i++)
            array[i] = tmp[i];
        return res;
    }
}

相關文章