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

数组中的逆序对

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5

import java.util.*;


public class Solution {
    private int count = 0;
    private final int MOD = 1000000007;

    public int InversePairs(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        mergeSort(nums, 0, nums.length - 1);
        return count;
    }

    private void mergeSort(int[] nums, int start, int end) {
        if (start >= end) {
            return;
        }
        int mid = (start + end) / 2;
        mergeSort(nums, start, mid);
        mergeSort(nums, mid + 1, end);
        merge(nums, start, mid, end);
    }

    private void merge(int[] nums, int start, int mid, int end) {
        int[] temp = new int[end - start + 1];
        int i = start, j = mid + 1, k = 0;

        while (i <= mid && j <= end) {
            if (nums[i] > nums[j]) {
                count = (count + (mid - i + 1)) % MOD;
                temp[k++] = nums[j++];
            } else {
                temp[k++] = nums[i++];
            }
        }

        while (i <= mid) {
            temp[k++] = nums[i++];
        }

        while (j <= end) {
            temp[k++] = nums[j++];
        }

        System.arraycopy(temp, 0, nums, start, temp.length);
    }
}

使用归并排序计算逆序对数量,其实就是先拆分,在合并,在合并中,如果对于nums[i]-nums[mid]与nums[j]-nums[end],如果nums[i]>nums[j],则左子数组都是与nums[j]形成了逆序对,然后把nums[j]放入新数组中,继续比较nums[i]与nums[j+1]; 如果nums[i]<nums[j],则把nums[i]放入新数组中,继续比较nums[i+1]与nums[j],两个数组比完,也就代表这部分的逆序数求出来的,且排好序了,直到只剩一个数组,就结束了。

一开始没理解的地方:

拆分为什么不见新数组:这是因为是隐式拆分,并未形成新的数组;

拆分时为什么要有mid,直接是start到end不是更好:这是因为mid每次重复计算,保证拆分范围是变动的。

新学习的方法的功能:

System.arraycopy 的方法签名如下:

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

参数说明:

  • src:源数组,你想要从这个数组中拷贝元素。
  • srcPos:源数组中的起始位置,从这个位置开始拷贝。
  • dest:目标数组,你想要拷贝元素到这个数组。
  • destPos:目标数组中的起始位置,从这个位置开始粘贴拷贝的元素。
  • length:要拷贝的元素数量
全部评论

相关推荐

刘湘_passion:太强了牛肉哥有被激励到
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务