版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/mmc_maodun/article/details/27520535

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27520535

题目描写叙述:
在数组中的两个数字,假设前面一个数字大于后面的数字。则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
输入:
每一个測试案例包括两行:
第一行包括一个整数n,表示数组中的元素个数。当中1 <= n <= 10^5。
第二行包括n个整数,每一个数组均为int类型。
输出:
相应每一个測试案例,输出一个整数,表示数组中的逆序对的总数。
例子输入:
4
7 5 6 4
例子输出:
5
    思路:最简单的方法是顺序数组,将每一个数字与后面的比較。统计逆序对的个数。这样的方法的时间复杂度为O(n*n)。这样的方法写出的代码在九度OJ上測试,会超时。剑指offer给出了归并排序的思路,这个有点难想到啊,也可能是我太弱了。根本没往这方面想。理解了思路,就不难了,将数组划分成两个子数组,再将子数组分别划分成两个子数组。统计每一个子数组内的逆序对个数,并将其归并排序,再统计两个子数组之间的逆序对个数,并进行归并排序。这就是归并排序的变种,在归并排序代码的基础上稍作改进就可以。
    合理还要注意一点:全局变量count不能声明为int型,必须为long long型。由于题目中说数组最大为10^5,那么最大逆序对为(10^5-1)*10^5/2。这个数大约在50亿左右,超过了int型的表示范围。
    AC代码例如以下:
#include<stdio.h>
#include<stdlib.h>/*
统计两个子数组之间的逆序对
*/
long long MergePairsBetweenArray(int *arr,int *brr,int start,int mid,int end)
{int i = mid;int j = end;int k = end;  //辅助数组的最后一位long long count = 0;//设置两个指针i,j分别从右往左依次比較。//将较大的依次放入辅助数组的右边while(i>=start && j>=mid+1){if(arr[i] > arr[j]){count += j-mid;brr[k--] = arr[i--];}elsebrr[k--] = arr[j--];}//将当中一个数组中还剩下的元素复制到辅助数组中,//两个循环仅仅会运行当中的一个while(i>=start)brr[k--] = arr[i--];while(j>=mid+1)brr[k--] = arr[j--];//从辅助数组中将元素复制到原数组中,使其有序排列for(i=end;i>k;i--)arr[i] = brr[i];return count;
}/*
统计数组中的全部的逆序对
*/
long long CountMergePairs(int *arr,int *brr,int start,int end)
{long long PairsNum = 0;if(start<end){int mid = (start+end)>>1;PairsNum += CountMergePairs(arr,brr,start,mid);    //统计左边子数组的逆序对PairsNum += CountMergePairs(arr,brr,mid+1,end); //统计右边子数组的逆序对PairsNum += MergePairsBetweenArray(arr,brr,start,mid,end); //统计左右子数组间的逆序对}return PairsNum;
}/*
将函数封装起来
*/
long long CountTotalPairs(int *arr,int len)
{if(arr==NULL || len<2)return 0;int *brr = (int *)malloc(len*sizeof(int));if(brr == NULL)exit(EXIT_FAILURE);long long sum = CountMergePairs(arr,brr,0,len-1);free(brr);brr = NULL;return sum;
}int main()
{int n;while(scanf("%d",&n) != EOF){int *arr = (int *)malloc(n*sizeof(int));if(arr == NULL)exit(EXIT_FAILURE);int i;for(i=0;i<n;i++)scanf("%d",arr+i);printf("%lld\n",CountTotalPairs(arr,n));free(arr);arr = NULL;}return 0;
}
/**************************************************************
    Problem: 1348
    User: mmc_maodun
    Language: C
    Result: Accepted
    Time:100 ms
    Memory:1696 kb
****************************************************************/

转载于:https://www.cnblogs.com/ldxsuanfa/p/10552397.html

【剑指offer】数组中的逆序对相关推荐

  1. 剑指offer 数组中的逆序对

    题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  2. 剑指Offer_35_数组中的逆序对

    题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  3. 2021-09-03剑指Offer51.数组中的逆序对

    class Solution {int[] nums, tmp;//表示未分配长度的数组指针?//java的默认权限是共有还是私有?public int reversePairs(int[] nums ...

  4. 剑指offer 数组中的逆数对

    链接:https://www.nowcoder.com/profile/8740530/codeBookDetail?submissionId=9156674 来源:牛客网class Solution ...

  5. 剑指offer35——数组中的逆数对

    题目:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 一种直观的思路是通过暴力破解的方法,时间复杂度为O(N*N).除此以 ...

  6. 8. 返回数组里出现次数最多的数字_剑指offer 数组中出现次数超过一半的数字

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  7. 剑指offer:数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  8. [剑指offer] 数组中只出现一次的数字

    本文首发于我的个人博客:尾尾部落 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 解题思路 法一:大家都能想到的HashMap法 法二:异或法 ...

  9. python剑指offer数组中出现次数超过一半的数字

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  10. 【排序】剑指offer:数组中重复的数字

    对数组进行排序,然后遍历判断,如果两个数相等,那么这两个数一定相邻 代码: class Solution { public:int duplicate(vector<int>& n ...

最新文章

  1. Linux进程突然挂死,当主进程突然死亡时,我该如何杀死linux spawnProcess?
  2. 爱鲜蜂签约神策数据 让精细化运营落地企业
  3. css中定义超级链接的样式
  4. 设计模式(2)--Singleton(单例模式)--创建型
  5. POJ3096Surprising Strings(map)
  6. C/C++,Qt,Python,OpenCV小项目实战-实时桌面颜色查询
  7. 【cocos2d-x从c++到js】12:回调函数1——按键回调
  8. 购买服务器机柜需要考量的几个问题
  9. Hive常见函数大全
  10. C#中的Boolean类型
  11. ⚡自组织映射(SOM)神经网络⚡Python实现 |Python技能树征题
  12. 测试笔记本续航的软件,笔记本续航测试
  13. 微信小程序蓝牙打印(中文乱码已解决)-分包发送(安卓和苹果手机均兼容)
  14. 【BUG】ELF文件执行时出现段错误Segmentation fault,解决:使用010编辑器修改ELF文件不可执行段权限
  15. 1788 数量的类模板
  16. 详解密码学中几种常见密码加密与解密
  17. 企业和团队如何创建高效实用的知识管理体系
  18. python数据分析与应用第四章课后实训答案_应用回归分析,第4章课后习题参考答案...
  19. NTLM-relay攻击的原理与实现
  20. 打败魔王(这是2022中兴捧月打榜的一道题)

热门文章

  1. LAMP默认安装路径
  2. 借助模糊测试 深耕细作你的压力测试
  3. [Teaching] [Silverlight] 30秒快速建立遊戲迴圈 (Game Loop)
  4. 怎样给 ActiveX 控件签名并打包发布
  5. 【恋上数据结构】基数排序、桶排序、休眠排序
  6. shell中的正则表达式
  7. python环境配置(一)——Linux下将python2.6升级到2.7 安装pip 以及升级中遇到问题的解决方法
  8. [转][进阶]-Python3 异步编程详解
  9. 1月份Github上热门Python开源项目
  10. JAVA将list2合并到list1_java如何将两个list合并的问题