使用归并排序求解数组逆序对个数

来源:互联网 发布:hr 知乎 编辑:程序博客网 时间:2024/05/16 10:05

给出一个数组,用n*log(n)的事件复杂度,求解逆序对个数,如

8,2,3, 1,6, 5, 9

逆序对有8个


array = [8, 2, 3, 1, 6, 5, 9]def merge(a1, n1, a2, n2, a, n):    c = c1 = c2 =0    count = 0    while c < n:        if c1 == n1:            while c < n:                a[c] = a2[c2]                c = c + 1                c2 = c2 + 1        elif c2 == n2:            while c < n:                a[c] = a1[c1]                c = c + 1                c1 = c1 + 1        else:            if a1[c1] > a2[c2]:                a[c] = a2[c2]                count = count + n1 - c1                c = c + 1                c2 = c2 + 1            else:                a[c] = a1[c1]                c = c + 1                c1 = c1 + 1    return countdef Sort(a):    n = len(a)    if n == 1: return 0    n1 = n/2    n2 = n - n1    a1 = a[:n1]    a2 = a[n1:]    count1 = Sort(a1)    count2 = Sort(a2)    c = c1 = c2 = 0    count = count1 + count2 + merge(a1, n1, a2, n2, a, n)    return countprint Sort(array)


java实现,使用两个数组,使用O(n)的辅助空间开销(上一种方法使用了O(nlog(n))的空间开销)

public class InverseCount {public static int Count(int [] data, int [] copy, int s, int e){if(s>=e) {return 0;}int mid = (e-s)/2+s;int count = 0;count += Count(copy, data, s, mid);count += Count(copy, data, mid+1, e);int i = s, j = mid + 1, c = s;while(i<=mid&&j<=e){if(data[i]<=data[j]){copy[c++] = data[i++];}else{copy[c++] = data[j++];count += (mid-i+1);}}while(i<=mid){copy[c++] = data[i++];}while(j<=e){copy[c++] = data[j++];}return count;}public static void main(String [] args){int [] d = {7, 5, 6, 4, 1, 6}, c = {7, 5, 6, 4, 1, 6};int count = Count(d, c, 0, 5);System.out.println(count);for(int k=0; k<6; k++)System.out.print(d[k]+" ");System.out.println();for(int k=0; k<6; k++)System.out.print(c[k]+" ");}}


0 0