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;
        }
    }
  • 相关阅读:
    Atitit js nodejs下的进程管理wmic process进程管理
    Atitit 提取sfit特征点,并绘制到原图上
    Atitit 局部图查找大图 方法 与 说明
    Atitit java读取tif文件为空null的解决 图像处理
    Aititi 特征点检测算法与匹配的前世今生与历史传承attilax总结v4
    Atitit it行业图像处理行业软件行业感到到迷茫的三大原因和解决方案
    Atitit js nodejs 图像处理压缩缩放算法 attilax总结
    Atitit 2017年第68界机器视觉图像处理学术大会会议记要attilax总结自建学院自颁学位理论
    Atitit nodejs js 获取图像分辨率 尺寸 大小 宽度 高度
    Atitit 图像处理之编程之类库调用的接口api cli gui ws rest  attilax大总结.docx
  • 原文地址:https://www.cnblogs.com/silentteller/p/11991571.html
Copyright © 2011-2022 走看看