基本介紹
定義,求解逆序對個數問題,問題描述,求解方法,
定義
對於一個包含N個非負整數的數組A[1..n],如果有i < j,且A[ i ]>A[ j ],則稱(A[ i] ,A[ j] )為數組A中的一個逆序對。
例如,數組(3,1,4,5,2)的逆序對有(3,1),(3,2),(4,2),(5,2),共4個。
求解逆序對個數問題
問題描述
給定一個數組,求該數組中包含多少個逆序對。
求解方法
方法一:最原始的方法,利用兩重循環進行枚舉。該算法的時間複雜度為O(n^2)。
C++代碼如下:
int count_inversion(int a[], int n){ int count = 0; for(int i = 0; i < n - 1; ++i) for(int j = i + 1; j < n; ++j) if(a[i] > a[j]) count += 1; return count;}
Pascal代碼如下:
var i,j,k,n:longint; a:array[1..1000000] of longint;begin readln(n); for i:=1 to n do read(a[i]); k:=0; for i:=1 to n-1 do for j:=i+1 to n do if a[i]>a[j] then inc(k); writeln(k);end.
C++代碼如下:
void merge_inversion(int *a, int l, int m, int r){ int i, j, k; int n1 = m-l+1; int n2 = r-m; int *L = (int*)calloc(n1, sizeof(int)); int *R = (int*)calloc(n2, sizeof(int)); for(i=l; i<=m; i++) L[i-l] = a[i]; for(j=m+1; j<=r; j++) R[j-m-1]=a[j]; i = 0; j = 0; for(k=l; k<=r; k++) { if(i<n1&&j<n2) { if(L[i]<R[j]) { a[k]=L[i++]; globa_count+=n2-1-j+1; } else a[k]=R[j++]; } else break; } //process if one part terminately early if(i==n1 && j<n2) while(j<n2) a[k++] = R[j++]; if(i<n1 && j==n2) while(i<n1) a[k++] = L[i++]; free(L); free(R);}
Pascal代碼如下:
Type arr=array[1..1000000]of longint;Var i,n:longint; k:int64; a,b:arr;Procedure merge(var a:arr;l,x,r:longint); var i,j,p:longint;//p:position begin i:=l; j:=x+1; p:=l; while (p<=r) do begin if(i<=x)and((j>r)or(a[i]<=a[j])) then begin b[p]:=a[i]; inc(i); end else begin b[p]:=a[j]; inc(j); inc(k,x-i+1); end; inc(p); end; for i:=l to r do a[i]:=b[i]; end;Procedure msort(var a:arr;l,r:longint); var x:longint; begin if (l<>r) then begin x:=(l+r)div 2; msort(a,l,x); msort(a,x+1,r); merge(a,l,x,r); end; end;Begin readln(n); for i:=1 to n do read(a[i]); k:=0; msort(a,1,n); writeln(k);End.