怎样求数组中逆序数对的个数(java)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样求数组中逆序数对的个数(java)相关的知识,希望对你有一定的参考价值。
求大神指点,最好有详细代码,谢谢。
参考技术A private static int method(int[] array)int count = 0;
for (int i = 0; i < array.length; i++)
for (int j = i + 1; j < array.length; j++)
if (array[i] > array[j])
count++;
return count;
private static int count = 0;
private void count(int[] array)
int length = array.length;
int left = (int) (length / 2 + 0.5);
int right = length / 2;
int[] leftArray = new int[left];
int[] rightArray = new int[right];
System.arraycopy(array, 0, leftArray, 0, left);
System.arraycopy(array, left, rightArray, 0, right);
if (left > 1 && right > 1)
count(leftArray);
count(rightArray);
Arrays.sort(leftArray);
Arrays.sort(rightArray);
mergeCount(leftArray, rightArray);
private void mergeCount(int[] leftArray, int[] rightArray)
int leftLength = leftArray.length;
int rightLength = rightArray.length;
while (leftLength > 0 && rightLength > 0)
if (leftArray[0] > rightArray[0])
count = count + leftLength;
System.arraycopy(rightArray, 1, rightArray, 0, rightLength - 1);
rightLength--;
else
System.arraycopy(leftArray, 1, leftArray, 0, leftLength - 1);
leftLength--;
private static Node[] nodes;
private static int[] tree;
private static int[] reflect;
private static int length;
private static int countArray(int[] array)
init(array);
return doCount();
private static int doCount()
for (int i = 0; i < length; i++)
reflect[nodes[i].pos] = i + 1;
int count = 0;
for (int i = 1; i <= length; i++)
update(reflect[i]);
count = count + i - sum(reflect[i]);
System.out.println(count);
return count;
private static void init(int[] array)
length = array.length;
nodes = new Node[length];
reflect = new int[length + 1];
tree = new int[length + 1];
for (int i = 0; i < length; i++)
nodes[i] = new Node();
nodes[i].value = array[i];
nodes[i].pos = i + 1;
Arrays.sort(nodes, Comparator.comparingInt(o -> o.value));
private static int lowbit(int x)
return x & (-x);
private static void update(int pos)
while (pos <= length)
tree[pos] += 1;
pos += lowbit(pos);
private static int sum(int pos)
int sum = 0;
while (pos > 0)
sum += tree[pos];
pos -= lowbit(pos);
return sum;
public static void main(String args[])
int[] array = 40000000, 20000000, 3000000, 534435454, 732123434, 167675688, 46565656, 8;
System.out.println(countArray(array));
//---------------//
class Node
int value;
int pos;
参考技术B const int LENGTH=100;
int temp[LENGTH]; //额外的辅助数组
int count=0;
void Merge(int * array,int first,int med,int last)
int i=first,j=med+1;
int cur=0;
while (i<=med&&j<=last)
if (array[i]<array[j])
temp[cur++]=array[i++];
else
temp[cur++]=array[j++];
<span style="color:#ff0000;">count+=med-i+1</span>; //核心代码,逆序数增加
while (i<=med)
temp[cur++]=array[i++];
while (j<=last)
temp[cur++]=array[j++];
for (int m=0;m<cur;m++)
array[first++]=temp[m++];
void MergeSort(int *array,int first,int last)
if (first==last)
return ;
int med=first+(last-first)/2;
MergeSort(array,first,med);
MergeSort(array,med+1,last);
Merge(array,first,med,last);
求逆序对(树状数组)
求逆序对
描述
给定一个序列a1,a2,…,an,如果存在iaj,那么我们称之为逆序对,求逆序对的数目
输入
第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。
N<=10^5。Ai<=10^5
输出
两行,第一行为所有逆序对总数,第二行为本质不同的逆序对总数。
输入
4 3 2 3 2
输出
3 1
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define mod 1000000009 4 #define lowbit(x) x&(-x) 5 using namespace std; 6 ll n,sum[100005],b[100005],ans,num,f[100005],in[100005]; 7 struct data{ 8 ll v,id; 9 }a[100005]; 10 void add(ll x,ll val) 11 { 12 while(x<=100001) 13 { 14 sum[x]+=val; 15 x+=lowbit(x); 16 } 17 } 18 ll ask(ll x) 19 { 20 ll ans=0; 21 while(x) 22 { 23 ans+=sum[x]; 24 x-=lowbit(x); 25 } 26 return ans; 27 } 28 int main() 29 { 30 scanf("%lld",&n); 31 for(ll i=1;i<=n;i++) 32 scanf("%lld",&a[i].v); 33 for(ll i=1;i<=n;i++) 34 { 35 add(a[i].v,1); 36 ans+=i-ask(a[i].v); 37 } 38 memset(sum,0,sizeof(sum)); 39 for(ll i=n;i>=1;i--) 40 { 41 if(in[a[i].v]==0) 42 { 43 add(a[i].v,1); 44 in[a[i].v]=1; 45 } 46 num-=f[a[i].v]; 47 f[a[i].v]=ask(a[i].v-1); 48 num+=f[a[i].v]; 49 } 50 printf("%lld %lld",ans,num); 51 return 0; 52 }
以上是关于怎样求数组中逆序数对的个数(java)的主要内容,如果未能解决你的问题,请参考以下文章