今天学习算法导论第二章中提到的逆序对问题,思前想后采用2种方式比较妥当。具体见下述分析。
逆序对问题:
逆序对(inversion pair)是指在序列{a0,a1,a2...an}中,若ai<aj(i>j),则(ai,aj)上一对逆序对。而逆序数 (inversion number)顾名思义就是序列中逆序对的个数。例如: 1 2 3是顺序,则逆序数是0;1 3 2中(2,3)满足逆序对的条件,所以逆序数只有1; 3 2 1中(1,2)(1,3)(2,3)满足逆序对,所以逆序是3。由定义不难想象,序列n的逆序数范围在[0,n*(n-1)/2],其中顺序时逆序数为 0,对于一个倒序的自然序列{an,an-1,an-2.......3,2,1}来说,是一个完全逆序序列。根据定义我们可以很方便的得到该序列的逆序对总数为 T(N)=∑(i,i<=n)fn,其中fn=(n-1)得到最终结果为T(N)=N*(N-1)/2.
就我所知,目前求这种逆序对最快的算法是利用归并排序,其时间复杂度为O(nlgn), 空间复杂度为O(n)
这里我给出一个O(n*n)的循环算法和一个O(nlgn)的分治算法。
- 循环算法,见下面代码:
public int countByLoop(Integer a[]){
int count=0;
for(int i=0;i<a.length;i++){
for(int j=a.length-1;j>i;j--){
if(a[i]>=a[j]){
count++;
System.out.printf("found=(i=%d,j=%d,a[i]=%d,a[j]=%d)\n",i,j,a[i],a[j]);
}
}
}
return count;
}
2. 分治算法实现如下
public int count(Integer a[],int low,int high){
int count=0;
if(low<high){
int mid=(low+high)/2;
count+=count(a,low,mid); //分治先计算左边的数组
count+=count(a,mid+1,high); //计算右边的数组
count+=mergeCount(a,low,mid,high); //合并两个结算结果
}
return count;
}
/**
* 采用分治法求得逆序对
* @param a
* @return
*/
public int count(Integer a[]){
return count(a,0,a.length-1);
}
private int mergeCount(Integer[] a, int low, int mid, int high) {
int count=0;
int i=low;
int j=mid+1;
while(i<=mid&&j<=high){
if(a[i]<=a[j]){
i++;
}else{
count+=mid-i+1;
for(int k=i;k<=mid;k++){
System.out.printf("(%d,%d)\n",a[k],a[j]);
}
j++;
}
}
while(i<=mid)i++;
while(j<=high)j++;
return count;
}
看到上述的算法,是不是觉得很眼熟呢,不错,其实和我们熟悉的归并排序算法很相似,只是这里不需要额外的辅助内存空间来保存排序
欢迎各位拍砖
分享到:
相关推荐
通过对逆序对统计实验的学习与实践,学生不仅加深了对归并排序算法的理解,还学会了如何利用算法解决实际问题。此外,通过编写和调试代码,学生的编程技能也得到了锻炼。该实验是理论与实践相结合的良好案例,有助于...
逆序对是算法竞赛中常见的概念,特别是在信息学奥赛中常常出现,它与排序、数组和二分查找等基础知识紧密相关。本知识点主要探讨如何有效地计算一个数组中的逆序对数量。 首先,我们来定义逆序对。在数组或序列A[1....
在学习过程中,课后习题是检验理解和掌握程度的重要环节,而“算法导论第三版课后习题答案”则为读者提供了参考与校验的资源。 ### 一、选择排序算法详解 **标题与描述中的知识点**:选择排序是一种简单的比较排序...
实验二--单链表逆序排列.pdf
总的来说,这组源码提供了一个实践《算法导论》理论知识的机会,无论是对合并排序的实现还是逆序对的计数,都是对数据结构和算法基础的巩固。通过实际编写和运行这些代码,读者可以更好地掌握这些重要概念,并为后续...
理解并能有效地处理逆序对是提升算法能力和解决问题的关键技能之一。 提供的压缩包文件“算法-理论基础- 排序- 逆序对问题(包含源程序).pdf”可能包含了关于逆序对问题的理论介绍、算法实现细节以及示例代码。...
### 第二版《算法导论》习题答案分析 #### 标题与描述解析 - **标题**:“第二版的算法导论习题...以上是对文档中部分习题解答的详细解析,旨在帮助读者更好地理解《算法导论》第二版中的一些核心概念和算法设计技巧。
### 知识点生成 #### 算法导论答案第二版:算法 ...通过以上分析,《算法导论》第二版不仅提供了对算法的深入理解和解释,还提供了一系列实用的例子和练习来帮助读者更好地掌握算法设计的基础知识和技术。
#### 标题:算法导论 第二版答案 - **核心内容**:本书提供的是《算法导论》第二版一书的课后习题解答。 - **适用对象**:适用于学习《算法导论》并希望验证自己解答正确性的学生。 #### 描述:麻省理工算法导论第...
以上知识点详细介绍了《算法导论》第三版中涉及的选择排序、二分搜索以及逆序对的概念与应用。这些内容不仅是学习算法的基础,也是理解更高级算法设计思路的重要基石。通过掌握这些核心知识点,读者可以更好地理解...
### 知识点总结 #### 一、《算法导论》概述 《算法导论》是一本经典的计算机科学教材,全面...以上是对《算法导论》英文答案部分知识点的详细解读和总结,希望能帮助读者更好地理解和掌握这些重要的算法原理和技术。
通过以上对《算法导论》课后习题的解答,我们可以看到,无论是基础的排序算法还是更复杂的搜索算法,都是建立在扎实的理论基础之上的。掌握这些核心算法不仅可以帮助我们解决实际问题,还能提高我们的编程能力和算法...
本报告主要涵盖了在西北某电子类大学的“算法导论”课程中的四个上机项目,涉及到了排序、查找、逆序对计算以及序列比对等核心算法。以下是对每个项目的详细说明: 1. **SortSum(项目1)** 这个项目的任务是判断...
综上所述,《算法导论》第二版课后答案涉及了许多重要的算法设计与分析技巧,包括数学归纳法证明、递归树方法的应用、快速排序算法的实现及其效率分析、以及动态规划算法的应用等方面的知识点。这些知识点不仅对于...
[Java算法练习]-数组逆序输出.java
### 知识点总结 #### 一、《算法导论》第三版答案解析 ...通过上述解析,我们可以看到《算法导论》不仅提供了丰富的理论知识,还给出了实际的应用示例和解决方案,是一本非常适合学习和研究算法的参考书籍。
根据提供的信息,我们可以总结出以下相关的IT知识点: ### 一、《算法导论》第三版答案解析 ...以上内容是对给定文档中的知识点进行了详细解读,涵盖了选择排序算法、二分查找算法以及逆序对的概念和计算方法等内容。
标题中的“算法-数组逆序重存放”是一个典型的编程问题,常见于信息学奥赛,如NOIP(全国青少年信息学奥林匹克联赛)等竞赛中。这个问题的核心是要求参赛者实现一个算法,能够将给定的数组按照逆序的方式重新排列。...