题解 | #数组中的逆序对#TOP20

思路:
二分法,假如左边的数比右边的大,2、1 这是一个逆序对,那例如 [4、3]、[2、1] 呢?以2为基准,当遍历到4的时候,有一个逆序对,右侧数组往后移,又是一个逆序对,然后左侧数组回到3位置,和右侧数组去匹配逆序对。假如我们先排好[4,3],[2,1]有一个逆序对,记录一下。然后将[4,3]变成[3,4],然后和[1,2]去匹配,3比1大,所以4都不需要遍历,直接3后面的所有数和1匹配都是逆序对。然后再用3和 2 比较,同理
图片摘抄自Dylan alt

public class Solution {
    public int InversePairs(int [] array) {
        if(array == null || array.length <= 1){
            return 0;
        }
        return mergeSort(array, 0 , array.length - 1) % 1000000007;
        
    }
  
    private int mergeSort(int[] array, int left, int right){
        int mid = left + (right - left) / 2;
        if(left < right){
             int leftCount = mergeSort(array, left, mid);
             int rightCount = mergeSort(array, mid + 1, right);
            int count =  leftCount + rightCount + merge(array,left, mid ,right);
            return count % 1000000007;
        }
        return 0;
    }
    private int merge(int[] array, int left, int mid, int right){
        int[] temp = new int[right - left + 1];
        int tempIndex = 0;
        //原数组的起点位置 就是在array中的位置
        int arrayIndex = left;
        //左子树的下标起点
        int leftIndex = left;
        //右子树的起始位置
        int rightIndex = mid + 1;
        int count = 0;
        while(leftIndex <= mid && rightIndex <= right){
            if(array[leftIndex] <= array[rightIndex]){
                //不是逆序对
                temp[tempIndex++] = array[leftIndex++];
            }else{
                //存在逆序对 左边比右边大
                temp[tempIndex ++] = array[rightIndex++];
                //左子树当前位置后都比这个数大,所以当前位置到mid位置都是逆序对
                //mid  - leftIndex  + 1 
                count += mid +1 -leftIndex;
                count %= 1000000007; 
            }
        }
        while(leftIndex <= mid){
            //左子树还没遍历完
            temp[tempIndex ++] = array[leftIndex ++];
        }
        while(rightIndex <= right){
            temp[tempIndex ++] = array[rightIndex++];
        }
        
        //left - right 这段数组已经排好序了 ,left ,mid 的数一定比mid + 1 ,right 小
        for(int num : temp){
            array[arrayIndex++] = num;
        }
        return count;
    }
}

面试必刷TOP101 文章被收录于专栏

面试必刷TOP101

全部评论

相关推荐

字节 飞书绩效团队 (n+2) * 15 + 1k * 12 + 1w
点赞 评论 收藏
分享
专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务