求N个元素的逆序数

题目:

求N个元素的逆序数

分析:

解法一:穷举,时间复杂度为O(n2)

解法二:使用归并排序计算逆序数,时间复杂度O(N*lngN)

使用分治思想,以mid值将序列分为左序列(left->mid),右序列(mid+1->right)。将左右子序列排序好之后,进行合并。合并时获得逆序数,因为左序列已经保证有序,当右序列的值小于左序列的值,逆序数 = (midel-li+1)。以此类推。

 /**
     * 利用归并排序计算逆序数
     * @param v 数字序列
     * @param l 左边界
     * @param r 有边界
     * @return 左右边界之间的逆序数
     */
    public static int findRev_order_num(int[] v,int l,int r){
        int len = r-l;
        if(len==0){
            return 0;
        }else if(len==1){
            if(v[l]>v[r]){
                int tmp = v[l];
                v[l] = v[r];
                v[r] = tmp;
                return 1;
            }
        }else{
            int mid = l+len/2;
            int leftNum = findRev_order_num(v,l,mid);
            int rightNum = findRev_order_num(v,mid+1,r);
            int merNum = 0;
            int[] dp = new int[r-l+1];
            int index=0;
            int i=l;
            int j=mid+1;
            while(i<=mid && j<=r){
                if(v[i]>v[j]){
                    merNum+=mid-i+1;
                    dp[index++] = v[j];
                    j++;
                }else{
                    dp[index++] = v[i];
                    i++;
                }
            }
            while(i<=mid){
                dp[index++] = v[i++];
            }
            while(j<=r){
                dp[index++] = v[j++];
            }
            System.arraycopy(dp,0,v,l,dp.length);
            return (leftNum+rightNum+merNum);
        }
        return 0;
    }

  

原文地址:https://www.cnblogs.com/dream-flying/p/13945096.html