逆序对的求解
2015-07-31 15:38
183 查看
<span style="font-size:18px;">题外话:</span>
<span style="font-size:18px;"><span style="white-space:pre"> </span>看了许多文章,觉得算法对于程序员还是很重要的,不管是以后是C/C++方向程序员还是Java程序员都一样,所以今天决定重新拾起算法。做算法还是用C++来写比较方便,最近都在搞Java ,已经一个学期没碰C++,写起来还真是痛苦。</span>
<span style="font-size:18px;">正题:</span>
<span style="font-size:18px;"><span style="white-space:pre"> </span>逆序对的概念:数组s[0...N]中如果i<j ,s[i]>j就表示有一个逆序对问题:对任意一个数组求其逆序对。</span>
<span style="font-size:18px;"><span style="white-space:pre"> </span>朴素的算法当然是暴力求解了,两个for循环进行判断,时间复杂度为n的平方。</span>
<span style="font-size:18px;"><span style="white-space:pre"> </span>这里重点讲利用分治策略求解:将一个数组分为两个子数组,分别求解子数组的逆序数,在加上两个数组比较后的逆序数,于是可递归求解递归式:<strong>t(q,r)=t(q,p)+t(p+1,r)+s</strong>;若两个是子数组L,R都是有序的情况下 if(L[i]>R[j]),则从L[i]~L[end]>R[j]都成立,于是有逆序数:<strong>s=end-i</strong>;一开始我的疑问时两个子数组的排序不会对逆序数造成影响吗?经过分析,L数组的元素不论位置如何,对于R数组的元素形成的逆序对是不变的,即逆序对中<a,b>中,a来自L,b来自R。好了,现在问题快解决了,我们要求分为两个有序子数组,能用到的排序方法是归并排序了,将逆序数的统计加入到归并排序中,所以算法最终的时间复杂度是nlogn,空间复杂度是n。</span>
</pre><pre name="code" class="cpp">/*求一个数组中逆序对个数时间:2015-07-31*/#include<iostream>using namespace std;int count=0;//治//完成两个数组的归并void f1(int *a,int q,int p,int r){int n1=p-q+1; //两个数组长度int n2=r-p;int *L=new int(n1);int *R=new int(n2);int i=0,j=0;for(i=0;i<n1;i++)L[i]=a[q+i];for(j=0;j<n2;j++)R[j]=a[p+1+j];i=0;j=0;int k=q;while( i<n1 && j<n2 ){if(L[i]<=R[j]){a[k++]=L[i++];}else{count+=n1-i;a[k++]=R[j++];}}while(i<n1)a[k++]=L[i++];while(j<n2)a[k++]=R[j++];}//分void f2(int *a,int q,int r){if(q>=r) return ;int p=(r+q)/2;f2(a,q,p);f2(a,p+1,r);f1(a,q,p,r);}void main(){int arry[5]={5,3,4,2,1};f2(arry,0,4);printf("%d\n",count);for(int i=0;i<5;i++){printf(" %d ",arry[i]);}}参考博客:http://blog.csdn.net/skywalkervvv/article/details/8546702。感谢博主,侵联删。
相关文章推荐
- 【Android本地开发技术:媒体开发】AVI视频格式解析
- 《深入理解Nginx 模块开发与架构解析》笔记之定时器
- Python学习资料汇总
- Qt 5.3 下OpenCV 2.4.11 开发(7)单通道直方图绘制
- eclipse配置本地服务
- String cannot be resolved to a type
- 滑动门的例子
- 【原创】相对完美的垂直居中popup(modal/dialog),无需监听window.resize事件
- 显示虚线
- leetcode 074 —— Search a 2D Matrix
- 如何实现HTTP DIGEST认证
- 探究Android系统中解析JSON数据的方式
- 判断填写的邮箱里是否有“@”
- 关于将Webpack,编译文件输出到不同的目录下
- C语言——计算文件大小(二)
- 黑马程序员-------集合框架之HashSet
- FFT模板
- 搞颠provider,factory 和service
- oracle,mysql,SqlServer三种数据库的分页查询总结
- Java File类学习笔记3:自定义一个类,读取文本内容到字符串