算法导论习题---求n个元素任何排列中逆序对的数量
来源:互联网 发布:淘宝有哪些靠谱的韩代 编辑:程序博客网 时间:2024/05/12 11:01
问题描述:
设A[1…n]是一个包含n个不同数的数组。如果在i < j的情况下,有A[i] > A[j],则(i,j)就称为A中的一个逆序对(inversion),(逆序对的元素是下标,而不是数组里的值)。给出一个算法,它能用Θ(nlgn)的最坏情况运行时间,确定n个元素的任何排列中逆序对的数目。
问题求解:
方法一:
循环从数组中取出一个元素k,然后从k之后的元素中找到比k小的元素个数,最后统计所有的个数即为排列中逆序对的数目。从数组中取元素的次数为n,每次取出一个元素后,需要遍历(n-i)次(i为当前元素的位置),其时间复杂度为
算法实现:
int CountInversions(const vector<int>& a){ int cnt = 0; for (size_t i = 0; i < a.size(); i++) { for (size_t j = i + 1; j < a.size(); j++) { if (a[i] > a[j]) cnt++; } } return cnt;}
方法二:插入排序
利用插入排序的方式来解决。
对数组用插入排序来做升序排列时,如果有元素需要移动,则每次移动时都相当于是找到了一个逆序对,因此插入队列中移动元素的次数,也就是排列中逆序对的数量。
但插入排序的时间复杂度为Θ(n^2),不符合题目要求。
方法三:修改归并排序(时间复杂度O(lgn))
归并排序的基本思想就是 Divide & Conquer: 将数组划分为左右两部分,归并排序左部分,归并排序右部分,然后 Merge 左右两个数组为一个新的数组,从而完成排序。
按照这个基本思想,我们也可以运用到计算逆序对中来。假设将数组划分左右两部分:
(1)左边部分的逆序对有 inv1 个
(2)右边部分的逆序对有 inv2 个
(3)剩余的逆序对必然是一个数出现在左边部分,一个数出现在右边部分,并且满足出现左边部分的数 a[i] > a[j]。左右两部分排序与否,不会影响这种情况下的逆序对数,因为左右两部分的排序只是消除了两部分内部的逆序对,而对于 a[i] 来自左边, a[j] 来自右边构成的逆序,各自排序后还是逆序。
接下来就需要在 Merge 的过程中计算 a[i], a[j] 分别来自左右两部分的逆序对数。
如下图所示,如果所有 a[i] 都小于 b[j] 的第一个数,显然是没有逆序的。只有当 a[i] > b[j] 是才会发生逆序,由于我们事先对 a[] 和 b[] 已经排好序,而所以如果发生 a[i] > b[j], 那么所有 a[ii] (ii > i) 也都满足 a[ii] > b[j], 也就是说和 b[j] 构成逆序的数有 {a[i], a[i+1]…a[end]},所以逆序数增加 end- i + 1个, 所以我们每次碰到 a[i] > b[j] 的情况, 逆序对数增加 (end - i + 1) 个即可。
算法的框架图:
伪代码:
The initial call is COUNT-INVERSIONS(A,1,n)
参考:http://www.cnblogs.com/python27/p/4381953.html
- 算法导论习题---求n个元素任何排列中逆序对的数量
- 算法学习笔记----确定n个元素的任何排列中逆序对的数目
- 题目2.给出一个算法,它能用O(nlgn)的最坏情况运行时间,确定n个元素的任何排列中逆序对的数目
- 《求n个元素的全排列》
- 确定n个元素的任何排序中逆序对数量
- n个元素的全排列算法
- 蓝桥杯常用算法知识点:【递归】求n个元素的全排列
- 递归求n个元素的全排列
- 运用递归求n个元素的全排列
- C#实现求n个元素的全排列
- n个元素里选取m个,求m < n时的排列(不是全排列!!!)的递归算法代码
- 【算法导论】第三版课后习题2-4逆序对
- 深度优先算法求含有N个元素的集合的全部组合(即:在集合中选1,2,3...N个元素的所有组合,不是排列)
- 算法导论求n个点的最小距离
- 算法导论9.3-8-设X[1..n]和Y[1..n]为两个数组,每个都包含n个已排好序的数,给出一个求数组X和数组Y中所有2n个元素的中位数
- 生成n个元素全排列的算法
- 递归算法生成n个元素的所有排列
- 笔记一:n个元素的所有排列递归算法
- 《编程珠玑》阅读小记(10) — 搜索
- STL学习笔记之容器--set
- VxWorks三元组资料
- apache kafka系列之server.properties配置文件参数说明
- ActivityThread
- 算法导论习题---求n个元素任何排列中逆序对的数量
- mysql乐观锁总结和实践
- leetcode 3 -- Longest Substring Without Repeating Characters
- FIFO先进先出置换算法
- 浙江大学PAT_甲级_1036. Boys vs Girls (25)
- ios图片拉伸的问题
- Python 的 urllib2
- keil工具之uvmpw文件
- 正则表达式语法