Pku acm 1007 DNA Sorting 排序算法解题报告(五)----求逆序数 排序

什么是逆序数:
跟标准列相反序数的总和,比如说,标准列是1 2 3 4 5,那么 5 4 3 2 1 的逆序数算法:看第二个,4之前有一个5,在标准列中5在4的后面,所以记1个,类似的,第三个 3 之前有 4 5 都是在标准列中3的后面,所以记2个,同样的,2 之前有3个,1之前有4个
将这些数加起来就是逆序数=1+2+3+4=10。
再举一个 2 4 3 1 5 。4 之前有0个 3 之前有1个 1 之前有3个 5 之前有0个
所以逆序数就是1+3=4。
归并排序(MegerSort)求逆序数思想:
如果比较任意两个数字,那么时间复杂度是 O(n^2),对于较大的n是无法接受的,MegerSort的时间复杂度是O(nlogn).
合并的时候一个指针指 i向左边的元素l,有个指针j指向右边的元素r,当r小于l的时候,左边i到mid中的元素则与r构成逆序对。只用将逆序数总数加上mid-i+1就可以了。关于这个的应用参见上一篇解题报告。
对于本题,由于字符串中字符的范围是确定的,只有 A C G T,所以可以在O(n)内求出逆序数方法是:至后向前插入字符,以下四个参数分别代表如果在左边加上A C G T,逆序数会加上多少,left_A left_C left_G left_T.首先初始化为0,然后至后向前插入字符,如果插入的是A:以后在前面插入C G T,逆序数都会增加,所以:left_C++;left_G++;left_T++;如果插入的是C:逆序数加上left_C,以后在前面插入G T,逆序数都会增加,所以:left_G++;left_T++;如果插入的是G:逆序数加上left_G,以后在前面插入T,逆序数都会增加,所以:left_T++;如果插入的是T:逆序数加上left_T,以后在前面插入字符,逆序数都不会增加。因此有代码:
    for(i=length-1;i>=0;i--)
    {
        a=str[i];
        switch(a)
        {
        case 'A':
            left_C++;
            left_G++;
            left_T++;
            break;
        case 'C':
            left_G++;
            left_T++;
            count+=left_C;
            break;
        case 'G':
            left_T++;
            count+=left_G;
            break;
        case 'T':
            count+=left_T;
            break;
        }
    }
    return count;
不过这种方法仅仅适合于求逆序数时范围确定的情况,其他情况需要归并排序求逆序数。
求完逆序数后还需要排序,以为逆序数都是整数,满足计数排序的条件,这里用计数排序。

带有详细注释的代码可以从http://download.csdn.net/user/china8848/获得。

你可能感兴趣的:(Pku acm 1007 DNA Sorting 排序算法解题报告(五)----求逆序数 排序)