【算法导论学习-011】数组中的逆序对个数(Counting inversions in an array)
来源:互联网 发布:潮汕的淘宝村 编辑:程序博客网 时间:2024/05/11 02:56
1、问题来源
《算法导论》P41思考题2-4:Let A[1..n] be an array of n distinct numbers. (i, j) is called an inversion of A if i < j and A[i] > A[j].
2、解决方案
参考1:http://www.geeksforgeeks.org/counting-inversions/
讨论区:http://stackoverflow.com/questions/337664/counting-inversions-in-an-array/338252#338252
方案1:不排序的双重循环(时间复杂度O(n^2))
public static int getInversions(int[] array) { int counter=0; for (int i = 0; i < array.length; i++) { for (int j = i+1; j < array.length; j++) { if (array[i]>array[j]) { counter++; } } } return counter; }方案2:归并排序过程中计算逆序对(《算法导论》提示的方法,复杂度O(nlgn))
以下过程图解请参照《算法导论》P35页,注意对比本博客中【算法导论学习-002】归并排序(MergeSort)的异同。
<span style="font-size:18px;">/** * 创建时间:2014年8月10日 下午4:12:19 * 项目名称:Test * @author Cao Yanfeng * @since JDK 1.6.0_21 * 类说明: */public class CountInversionsTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[] array={5,2,4,7,1,3,2,6};// int result=getInversions(array); int result=mergeSort(array, 0, array.length-1); System.out.println(result); } public static int mergeSort(int[] arr, int start, int end) { if (start < end) { int middle = (start + end) >>> 1; </span><span style="font-size:18px;color:#cc0000;"><strong> int l=mergeSort(arr, start, middle); int r=mergeSort(arr, middle + 1, end); int m=mymerge(arr, start, middle, end); return l+r+m; }else { return 0;</strong></span><span style="font-size:18px;"> } } /* * 归并排序的思路:首先将arr分成两部分,用leftArray和rightArray暂存,然后从头开始比较leftArray和rightArray, * 谁小谁放入arr,相应指针移动 * 小技巧:leftArray和rightArray都增多最后一位,存放Integer.MAX_VALUE,用于不让它移动到最后 */ public static int mymerge(int[] arr, int start, int middle, int end) { /*拆分数组为leftArray和rightArray*/ int leftArrayLength = middle - start + 1; int rightArrayLength = end - middle; int[] leftArray = new int[leftArrayLength + 1];//多一位 int[] rightArray = new int[rightArrayLength + 1];//多一位 for (int i = 0; i < leftArrayLength; i++) { leftArray[i] = arr[start + i]; } for (int i = 0; i < rightArrayLength; i++) { rightArray[i] = arr[middle + 1 + i]; } /*多的最后一位记得要赋最大值*/ rightArray[rightArrayLength] = Integer.MAX_VALUE; leftArray[leftArrayLength] = Integer.MAX_VALUE; /*算法的关键部分,左右指针移动*/ int j = 0; int k = 0; </span><strong style="font-size: 16px;"><span style="color:#993300;"> int number=0;</span></strong><span style="font-size:18px;"> for (int i = start; i <= end; i++) { if (leftArray[j] </span><span style="color:#cc0000;font-size: 16px;"><strong><=</strong></span><span style="font-size:18px;"> rightArray[k]) { arr[i] = leftArray[j]; j++; } else { arr[i] = rightArray[k]; k++; </span><span style="color:#990000;font-size: 16px;"><strong> number+=leftArrayLength-j;</strong></span><span style="font-size:18px;"> } } return number; } }</span>
方案3:制作数组排序后的副本,利用原数组每个元素在副本中进行二分搜索(复杂度O(nlgn))
例如: int[] array={5,2,4,7,1,3,2,6};
制作排序后的副本 int[] temp={1,2,2,3,4,5,6}
array[0]=5,在temp中二分搜索,得到下表index=5,比它小的有inversions=index-0=5个
temp去除5,int[] temp={1,2,2,3,4,6}
array[1]=2,同理inversions=index-0=1个
同理,对于之后的inversions分别是 3,4,1,0,,0,总计5+1+3+4+1=14个
*******************************************************************************************************************************************************最后说明,对于一系列数来说,他们的所有排列的逆序对的期望是:n(n-1)/4。
讨论区:http://stackoverflow.com/questions/7804681/the-expected-number-of-inversions-from-introduction-to-algorithms-by-cormen
0 0
- 【算法导论学习-011】数组中的逆序对个数(Counting inversions in an array)
- Count Inversions in an array (求数组中的逆序对个数)
- Counting Inversions 统计逆序数算法
- SGU 180 Inversions(树状数组求逆序对)
- 《算法导论》中的逆序数对问题
- 算法导论习题2-4 Inversions 逆序数
- 算法导论--逆序对
- sgu-180 Inversions 裸题:求逆序对个数
- Counting Inversion Pairs in an Array
- 算法导论 逆序对问题
- 算法导论 逆序对问题
- 算法导论 逆序对问题
- 面试算法(三十六)数组中的逆序对
- 【算法】数组中的逆序对的总数
- 算法题目---数组中的逆序对
- 求数组逆序对个数
- 数组解逆序对个数
- 《算法导论》6、计算一个数组中逆序数的个数(C++,使用合并排序改编)
- 彻底研究mouseover mouseout mouseenter mouseleave
- 决策树小结----统计学习方法读书笔记
- vs2010修改状态栏的CStatusBar指针的的SetPaneText()方法时死活不对问题
- jsp三大编译指令、七大处理指令、九大内置对象简单笔记
- LeetCOde --- Max Points on a Line
- 【算法导论学习-011】数组中的逆序对个数(Counting inversions in an array)
- StateListDrawable资源
- iOS block回调
- 算法复习--shell排序
- Zedboard & Zynq 图像采集 视频开发 (四) Linux 系统搭建&Frame Buffer设计
- Regular cast vs. static_cast vs.dymamic_cast in C++
- Android开发之对话框高级应用
- xx新博客成立
- 047:hibernate:关联关系的CRUD_cascade_fetch_1