求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; }