面试题51. 数组中的逆序对(Java)(归并排序)

1 题目

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

示例 1:

输入: [7,5,6,4]
输出: 5

限制:

0 <= 数组长度 <= 50000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2 Java

2.1 方法一(归并)

其实本题就是求,将数组排序,需要交换多少对连续元素(不能跨两三个元素交换,一个一个来)
冒泡、插入都可以做,但超时
希尔由于出现大跨度交换,不行
归并排序虽然有大跨度交换,但每次都是在子问题中,不影响相邻子问题的逆序组数

class Solution {
    int ans = 0;

    public int reversePairs(int[] nums) {
        mergeSort(nums);
        return ans;
    }

    public int[] mergeSort(int[] nums){
        if(nums.length <= 1)    return nums;

        int mid = nums.length / 2;
        int[] left = Arrays.copyOfRange(nums, 0, mid);
        int[] right = Arrays.copyOfRange(nums, mid, nums.length);

        return merge(mergeSort(left), mergeSort(right));
    }

    public int[] merge(int[] left, int[] right){
        int l = 0, r = 0, lMax = left.length, rMax = right.length;
        int[] arrs = new int[lMax + rMax];
        while(l < lMax || r < rMax){
            if(l < lMax && r < rMax){
                if(left[l] <= right[r])  arrs[l + r] = left[l++];
                else if(left[l] > right[r]){
                    arrs[l + r] = right[r++];
                    ans += lMax - l;            // 比起原始归并排序,唯一添加的代码
                }
            }
            else if(l < lMax)   arrs[l + r] = left[l++];
            else if(r < rMax)   arrs[l + r] = right[r++];
        }
        return arrs;
    }
}
发布了131 篇原创文章 · 获赞 0 · 访问量 2268

猜你喜欢

转载自blog.csdn.net/weixin_43969686/article/details/105269120