zoukankan      html  css  js  c++  java
  • 【剑指Offer面试编程题】题目1348:数组中的逆序对--九度OJ

    题目描述:
    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
    输入:
    每个测试案例包括两行:
    第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
    第二行包含n个整数,每个数组均为int类型。
    输出:
    对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。

    样例输入:

    4
    7 5 6 4

    样例输出:
    

    5

    【解题思路】本题还是有一定的难度的,首先我们不可能通过遍历的方案来完成,时间复杂度过高。然后我们可以想象,是否我们可以通过分块完成,完成字块的统计后,我们使字块有序,然后继续统计其他字块。最后我们合并统计字块。我们融入一种合并排序的思想,通过小块的统计并有序来构造更大的有序块,直到最后全部合并完成。对于两个有序小块之间包含的逆序对,我们只需要判断有限的组合即可完成统计。

    AC code:

    #include <cstdio>
    #include <vector>
    using namespace std;
     
    int aa[50005],bb[50005];
     
    long long merge(int num[],const int&a,const int &b)
    {
      if(b-a==1)
        return 0;
      long long mid=((a+b)>>1),re=0;
      re+=merge(num,a,mid);
      re+=merge(num,mid,b);
      int acnt=0,bcnt=0;
      for(int i=a;i<mid;++i)
        aa[acnt++]=num[i];
      for(int i=mid;i<b;++i)
        bb[bcnt++]=num[i];
      int numidx=a,aidx=0,bidx=0;
      while(aidx<acnt && bidx<bcnt)
      {
        if(aa[aidx]>bb[bidx])
        {
          re+=bcnt-bidx;
          num[numidx++]=aa[aidx++];
        }else
          num[numidx++]=bb[bidx++];
      }
      while(aidx<acnt)
        num[numidx++]=aa[aidx++];
      while(bidx<bcnt)
        num[numidx++]=bb[bidx++];
      return re;
    }
     
    int main()
    {
      int n;
      while(scanf("%d",&n)!=EOF)
      {
        long long cnt=0;
        int num[100002];
        for(int i=0;i<n;++i)
        {
          scanf("%d",&num[i]);
        }
        cnt=merge(num,0,n);
        printf("%lld
    ",cnt);
      }
      return 0;
    }
    /**************************************************************
        Problem: 1348
        User: huo_yao
        Language: C++
        Result: Accepted
        Time:100 ms
        Memory:1732 kb
    ****************************************************************/
    
    题目链接:http://ac.jobdu.com/problem.php?pid=1348

    九度-剑指Offer习题全套答案下载:http://download.csdn.net/detail/huoyaotl123/8276299



  • 相关阅读:
    HDU 5213 分块 容斥
    HDU 2298 三分
    HDU 5144 三分
    HDU 5145 分块 莫队
    HDU 3938 并查集
    HDU 3926 并查集 图同构简单判断 STL
    POJ 2431 优先队列
    HDU 1811 拓扑排序 并查集
    HDU 2685 GCD推导
    HDU 4496 并查集 逆向思维
  • 原文地址:https://www.cnblogs.com/huoyao/p/4248885.html
Copyright © 2011-2022 走看看