怎样求数组中逆序数对的个数(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)的主要内容,如果未能解决你的问题,请参考以下文章

白话经典算法系列之九 从归并排序到数列的逆序数对(微软笔试题)

HDU 4911 Inversion 树状数组求逆序数对

Ping pong(POJ 3928)

CodeForces911D 逆序对

HDU 4944 逆序数对

归并排序求逆序数对 hdu2689