美文网首页
51-数组中的逆序对

51-数组中的逆序对

作者: 一方乌鸦 | 来源:发表于2020-05-07 09:38 被阅读0次

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

    思路使用归并排序
    首先要会写归并排序:

    public class MergeSort {
        private static Comparable[] aux;
    
        public static void sort(Comparable[] a) {
            aux = new Comparable[a.length];
            sort(a, 0, a.length - 1);
        }
    
        private static void sort(Comparable[] a, int lo, int hi) {
            if (lo >= hi) return;
            int mid = lo + (hi - lo) / 2;
            sort(a, lo, mid);
            sort(a, mid + 1, hi);
            merge(a, lo, mid, hi);
        }
    
        private static void merge(Comparable[] a, int lo, int mid, int hi) {
            int i = lo, j = mid + 1;
            for (int k = lo; k <= hi; k++) aux[k] = a[k];
            for (int k = lo; k <= hi; k++) {
                if (i > mid) {
                    a[k] = aux[j++];
                } else if (j > hi) {
                    a[k] = aux[i++];
                    // 必须是 less(aux[j], aux[i]),不能为less(aux[i], aux[j])
                    // 保证归并排序稳定性
                } else if (less(aux[j], aux[i])) {
                    a[k] = aux[j++];
                } else {
                    a[k] = aux[i++];
                }
            }
        }
    
        private static boolean less(Comparable a, Comparable b) {
            return a.compareTo(b) < 0;
        }
    }
    

    答案:

    class Solution {
        private int[] aux;
        public int reversePairs(int[] a) {
            if (a == null || a.length == 0) return 0;
            aux = new int[a.length];
            return getCount(a, 0, a.length - 1);
        }
    
        private int getCount(int[] a, int lo, int hi) {
            if (lo >= hi) return 0;
            int mid = lo + (hi - lo) / 2;
            int left = getCount(a, lo, mid);
            int right = getCount(a, mid + 1, hi);
            if (a[mid] <= a[mid + 1]) {
                return left + right;
            }
            int cross = merge(a, lo, mid, hi);
            return left + right + cross;
        }
    
        private int merge(int[] a, int lo, int mid, int hi) {
            int i = lo, j = mid + 1, count = 0;
            for (int k = lo; k <= hi; k++) aux[k] = a[k];
            for (int k = lo; k <= hi; k++) {
                if (i > mid) {
                    a[k] = aux[j++];
                } else if (j > hi) {
                    a[k] = aux[i++];
                } else if (aux[j] < aux[i]) {
                    a[k] = aux[j++];
                    count += mid - i + 1;
                } else {
                    a[k] = aux[i++];
                }
            }
            return count;
        }
    }
    

    相关文章

      网友评论

          本文标题:51-数组中的逆序对

          本文链接:https://www.haomeiwen.com/subject/bvgqghtx.html