数组中的逆序对

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

利用归并排序的思想:

归并排序的改进,把数据分成前后两个数组(递归分到每个数组仅有一个数据项),合并数组,合并时,出现前面的数组值array[i]大于后面数组值array[j]时;则前面数组array[i]~array[mid]都是大于array[j]的,count += mid+1 - i。

public class Solution {
    public int InversePairs(int [] array) {
        if (array == null)
            return 0;
        return mSort(array, 0, array.length-1) % 1000000007;
    }

    public int mSort(int[] arr, int left, int right) {
        if(left >= right)
            return 0;
        int mid = (left + right) / 2;

        int leftcnt = mSort(arr, left, mid) % 1000000007; //递归排序左边
        int rightcnt = mSort(arr, mid+1, right) % 1000000007; //递归排序右边
        int cnt = merge(arr, left, mid, right) % 1000000007; //合并
        return (leftcnt+rightcnt+cnt) % 1000000007;
    }

    public int merge(int[] arr, int left, int mid, int right) {
        //[left, mid] [mid+1, right]
        int[] temp = new int[right - left + 1]; //中间数组

        int i = mid;
        int j = right;
        int k = right - left;
        int cnt = 0;
        while(i >= left && j > mid) {
            if(arr[i] <= arr[j]) {
                temp[k--] = arr[j--];
            }
            else {
                temp[k--] = arr[i--];
                cnt += j - mid;
                if (cnt >= 1000000007) {
                    cnt %= 1000000007;
                }
            }
        }

        while(i >= left) {
            temp[k--] = arr[i--];
        }

        while(j > mid) {
            temp[k--] = arr[j--];
        }

        for(int p=0; p<temp.length; p++) {
            arr[left + p] = temp[p];
        }
        return cnt;
    }
}
时间: 2024-08-14 03:40:53

数组中的逆序对的相关文章

编程算法 - 数组中的逆序对 代码(C)

数组中的逆序对 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 在数组中的两个数字如果前面一个数字大于后面的数字, 则这两个数字组成一个逆序对. 输入一个数组, 求出这个数组中的逆序对的总数. 使用归并排序的方法, 辅助空间一个排序的数组, 依次比较前面较大的数字, 算出整体的逆序对数, 不用逐个比较. 时间复杂度: O(nlogn) 代码: /* * main.cpp * * Created on: 2014.6.12 * Author:

剑指offer (36) 数组中的逆序对

题目:在数组中的两个数字如果前面一个数字大于后面一个数字,则这两个数字组成一个逆序对 题解分析: 首先应该想到很简单的一种解法,顺序遍历数组,对每个数,逐个比较该数字和其以后的数字,T(n) = O(n^2) (1)总体的意思就是将数组分成两段,首先求段内的逆序对数量,比如下面两段代码就是求左右两端数组段内的逆序对数量 count += Merge(data, temp, first, mid);//找左半段的逆序对数目 count += Merge(data, temp, mid + 1, e

时间空间效率的平衡:数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000000007 输入描述: 题目保证输入的数组中没有的相同的数字 数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2*10^5 输入例子: 1,2,3,4,5,6,7,0 输出例子: 7

数组中的逆序对-剑指Offer

数组中的逆序对 题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路 如果扫描整个数组,每个数字跟后面的数字比较大小,整体的复杂度是O(n^2) 可以利用归并排序的算法的思想,在排序的同时判断前后两个子序列中存在的逆序对,都是从后往前排,如果前面的数大于后面的数,因为都是已经排好序的所以前面的数一定比后面的数都大,逆序对为后面剩下的元素的数量,然后正常排序:若小于,则这个元素不产生逆序对,正常排序.时间复杂度

剑指offer 数组中的逆序对

题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000000007 输入描述: 题目保证输入的数组中没有的相同的数字 数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2*10^5 示例1 输入 1,2,3,4,5,6,7,0 输出 7 思路:归并排序的思路.具体参考剑指

数组中的逆序对(分治)

题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组中的元素个数.其中1 <= n <= 10^5. 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出一个整数,表示数组中的逆序对的总数. 样例输入: 4 7 5 6 4 样例输出: 5 1.直接的做法是逐个统计,复杂度是N^2, 2.可以利用归并排序的思想,在排序过程中统

【剑指Offer学习】【面试题36:数组中的逆序对】

题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 举例分析 例如在数组{7, 5, 6, 4 中, 一共存在5 个逆序对,分别是(7, 6).(7,5),(7, 4).(6, 4)和(5, 4). 解题思路: 第一种:直接求解 顺序扫描整个数组.每扫描到一个数字的时候,逐个比较该数字和它后面的数字的大小.如果后面的数字比它小,则这两个数字就组成了一个逆序对.假设数组中含有n 个数字.由于每个数字都要和O(n)个数字作

【Sorting】【Array】数组中的逆序对

数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组中的元素个数.其中1 <= n <= 10^5. 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出一个整数,表示数组中的逆序对的总数. 样例输入: 4 7 5 6 4 样例输出: 5 思路 分治的思想,统计两边内部的逆序对,以及左右两边之间的逆序对 代码 long

【剑指offer】数组中的逆序对

# @left part: [start, mid] # @right part: (mid, end] def merge(data, start, mid, end): if mid < start or end < mid: return 0 reverse = 0 ''' @ for start, it play as the start index of left part, and mid @ play as the end index of left part; @ mid +