牛客 BM20 数组中的逆序对【中等 归并排序 解逆序对】

题目

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=295&tqId=23260&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007

数据范围: 对于
50% 的数据, size≤10 ^4
对于 100% 的数据, size≤10 ^5

数组中所有数字的值满足
0≤val≤10 ^9

要求:空间复杂度 O(n),时间复杂度 O(nlogn)
输入描述:
题目保证输入的数组中没有的相同的数字
示例1
输入:
[1,2,3,4,5,6,7,0]
复制
返回值:
7
复制
示例2
输入:
[1,2,3]
复制
返回值:
0

解题核心

	归并排序

答案

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型
     */
    public int InversePairs (int[] nums) {
       //逆序对,核心:归并排序
        int n = nums.length;
        int step = 1;
        int[] ans = {0};
        while (step < n) {
            int l = 0;
            while (l < n) {
                int m = l + step - 1;
                if (m > n - 1) break;
                int r = Math.min(n - 1, m + step);
                merge(nums, l, m, r, ans);
                l = r + 1;
            }

            if (step > n / 2) break;
            step *= 2;
        }

//        for (int num : nums) {
//            System.out.print(num+"  ");
//        }
        //System.out.println("  ans:"+ ans[0]+" \r\n");
        return ans[0];
    }

    public static void merge(int[] arr, int l, int m, int r, int[] ans) {
        int[] help = new int[r - l + 1];
        int p1 = l, p2 = m + 1;
        int i = 0;
        while (p1 <= m && p2 <= r) {
            if (arr[p1] <= arr[p2]) {
                help[i++] = arr[p1++];
            } else {
                ans[0] += m - p1 + 1;
                ans[0] %= 1000000007;
                help[i++] = arr[p2++];
            }
        }

        while (p1 <= m) {
            help[i++] = arr[p1++];
        }

        while (p2 <= r) {
            help[i++] = arr[p2++];
        }

        for (int j = 0; j < help.length; j++) {
            arr[l + j] = help[j];
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵长辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值