您的位置:首页 > 产品设计 > UI/UE

用divide&conquer思想解决求逆序数对的问题

2009-10-24 01:58 387 查看
对于一个给定的数组中要去求其中逆序数对的个数,可以通过简单的两层for循环去逐个便利每一个数对,这样的思想是很容易就可以想到

的,但是其算法的复杂度确是O(n^2),为了降低算法的复杂度可以试着用divide&conquer思想去考虑这个问题。

对于一个数组{5,3,7,4,6,2,1,8},如果我们以中间(或者左中)为界限将其分成两个数组,只要知道这两个数组中的逆序对数和两边

的数所组成的逆序对数就是它所有的逆序对数了。而数组划分的递归结束点在两个数组都只有一个元素的时候,因此两数组中的逆序对数可以

通过递归求得。要去求分裂的两数组中的逆序对数可以这样去做:先将两数组按升序排序,若前一个数组的第一个元素比后一个的大,则说

明前一组的后面所有都要比后一组的第一个元素大,这样将较小的第一个元素去掉后,继续比较两个数组的第一个元素可以把所有的逆序对找

到。

下面是该算法的JAVA实现:

import java.util.*;

public class CountInversedNumbers{

public static int count=0; //记录逆序对个数;

public void sort_count(int []L){

int n=L.length;

int a=(int)(n/2+0.5);

int b=(int)(n/2);

int A[]=new int[a];

int B[]=new int[b];

for (int i=0;i<a;i++)

A[i]=L[i];

for (int j=0;j<b;j++)

B[j]=L[j+a]; //把单个数组划分成两个数组;

if(a>1&&b>1) {

sort_count(A);

sort_count(B); //递归的划分数组;

}

Arrays.sort(A);

Arrays.sort(B); //将数组排序;

merge_count(A,B);

}

public void merge_count(int []M, int[]N){ //求被划分的两个数组中元素组成的逆序对;

int c=M.length;

int d=N.length;

while(c>0&&d>0)

{

if(M[0]>N[0]) {

this.count=this.count+c;

for(int i=0;i<d-1;i++)

N[i]=N[i+1];

d--;

}

else{

for(int j=0;j<c-1;j++)

M[j]=M[j+1];

c--;

}

}

}

public static void main(String[] args){

int K[]={6,2,3,5,7,1,4,8};

CountInversedNumbers a=new CountInversedNumbers();

a.sort_count(K);

System.out.println(a.count); //输出结果是11;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐