zoukankan      html  css  js  c++  java
  • 剑指Offer-34.数组中的逆序对(C++/Java)

    题目:

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

    输入描述:

    题目保证输入的数组中没有的相同的数字

    数据范围:

    对于%50的数据,size<=10^4

    对于%75的数据,size<=10^5

    对于%100的数据,size<=2*10^5

    分析:

    可以从头扫描整个数组,每扫描到一个数字,就去计算后面的数字有多少比它小,这样操作的话时间复杂度是O(n^2),应该会超时。

    我们可以利用归并排序时合并两个有序的数组时候,更快的求得每次合并时的逆序对。

    例如合并[5,7]和[4,6]时从两个数组后面开始比较,选出较大的元素。

    因为7>6,所以7一定大于第二个数组剩下的所有元素,因为数组本身是有序的,可以立刻得到逆序对的个数,当后面的元素大时,不需要统计逆序对的个数,因为此时要大于前面剩下的所有元素,不构成逆序对。基于这种方法,时间复杂度控制在O(nlogn)。

     

    程序:

    C++

    class Solution {
    public:
        int InversePairs(vector<int> data) {
            return mergesort(data, 0, data.size()-1)%1000000007;
        }
        long long mymerge(vector<int> &vec, int left, int mid, int right){
            vector<int> temp(right-left+1,0);
            int index = right-left;
            long long countnum = 0;
            int i = mid;
            int j = right;
            while(i >= left && j >= mid+1){
                if(vec[i] > vec[j]){
                    countnum += (j-mid);
                    temp[index--] = vec[i--];
                }
                else{
                    temp[index--] = vec[j--];
                }
            }
            while(i >= left)
                temp[index--] = vec[i--];
            while(j >= mid+1)
                temp[index--] = vec[j--];
            for(int i = 0; i < temp.size(); ++i)
                vec[i+left] = temp[i];
            return countnum;
        }
        long long mergesort(vector<int> &vec, int left, int right){
            if(left >= right)
                return 0;
            int mid = (left + right) / 2;
            long long leftCount = mergesort(vec, left, mid);
            long long rightCount = mergesort(vec, mid+1, right);
            long long res = mymerge(vec, left, mid, right);
            return res + leftCount + rightCount;
        }
    };

    Java

    public class Solution {
        public int InversePairs(int [] array) {
            return (int)(mergesort(array, 0 , array.length-1)%1000000007);
        }
        public static long mymerge(int [] array, int left, int mid, int right){
            int[] temp = new int[right-left+1];
            int index = right-left;
            long countnum = 0;
            int i = mid;
            int j = right;
            while(i >= left && j >= mid+1){
                if(array[i] > array[j]){
                    countnum += (j-mid);
                    temp[index--] = array[i--];
                }
                else{
                    temp[index--] = array[j--];
                }
            }
            while(i >= left)
                temp[index--] = array[i--];
            while(j >= mid+1)
                temp[index--] = array[j--];
            for(i = 0; i < temp.length; ++i)
                array[i+left] = temp[i];
            return countnum;
        }
        public static long mergesort(int [] array, int left, int right){
            if(left >= right)
                return 0;
            int mid = (left + right) / 2;
            long leftCount = mergesort(array, left, mid);
            long rightCount = mergesort(array, mid+1, right);
            long res = mymerge(array, left, mid, right);
            return res + leftCount + rightCount;
        }
    }
  • 相关阅读:
    web安全-接入层注入
    web安全-密码安全
    web安全-传输安全
    Jenkins-安装
    RobotFramework-关键字
    RobotFramework-调用.py文件
    RobotFramework-登录
    SQL-行转列(PIVOT)实例1
    SQL-AdventureWorks样例数据库
    TestDescription文档描述测试过程
  • 原文地址:https://www.cnblogs.com/silentteller/p/11991571.html
Copyright © 2011-2022 走看看