数组中的逆序对(剑指offer)
来源:互联网 发布:平面美工 招聘 编辑:程序博客网 时间:2024/05/16 11:17
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007输入描述:题目保证输入的数组中没有的相同的数字数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2*10^5示例1:输入1,2,3,4,5,6,7,0输出7
首先分析题意,对于输入数组1,2,3,4,5,6,7,0, 逆序对为(1,0),(2,0)…(7,0)一共7个, 即对于数组中的每个数,其可以构成逆序对的个数为它后面且比它小的数的个数, 那么,最直观的方法显然是2层循环,当然,这样的话时间效率较低,那我们能不能找到更优的方法呢?
对于归并排序,我们应该都比较熟悉了,那么这个题目可不可以用归并排序的思路做呢? 显然是可以的。
以上图为例,我们把数组从中间分成左右2部分,然后分别计算左右2部分的逆序对的个数, 这部分递归就OK, 那我们现在的主要目的就是要计算左右2个数组之间的逆序对了, 左右2个数组计算逆序对后我们把他们弄成有序的,那计算2个有序数组之间的逆序对就只需要O(n)的时间复杂度了, 合并的时候我们需要额外的空间O(n)。
那么这样算法的时间复杂度T(n)=2*T(n/2)+O(n), 故时间复杂度为O(n*logn),空间复杂度为O(n).
这样就很easy了,是不是? 不说了,直接上代码
//合并左右2个数组,nums[left:mid]和nums[mid+1:right]int merge(vector<int>& nums, int left, int mid, int right){ int sum = 0, i = mid, j = right, temp = right - left; vector<int> a(right - left + 1, 0); //2个有序数组的合并 while (i >= left && j >= mid + 1) { if (nums[i]>nums[j]) { a[temp--] = nums[i]; sum = (sum + j - mid) % 1000000007; i--; } else { a[temp--] = nums[j]; j--; } } if (i<left) { while (j >= mid + 1) { a[temp--] = nums[j--]; } } if (j<mid + 1) { while (i >= left) { a[temp--] = nums[i--]; } } for (i = left; i <= right; i++) nums[i] = a[i - left]; return sum;}//递归计算int mergesort(vector<int>& nums, int left, int right){ if (left == right) return 0; int mid = (left + right) / 2; int leftcnt = mergesort(nums, left, mid) % 1000000007; int rightcnt = mergesort(nums, mid + 1, right) % 1000000007; return (leftcnt + rightcnt + merge(nums, left, mid, right)) % 1000000007;}int InversePairs(vector<int> data) { if (data.size() <= 1) return 0; return mergesort(data, 0, data.size() - 1);}
阅读全文
1 0
- 【剑指offer】数组中的逆序对
- 剑指offer 36 数组中的逆序对
- 剑指offer--数组中的逆序对
- 剑指Offer之 - 数组中的逆序对
- 剑指offer之数组中的逆序对
- 剑指offer 36 - 数组中的逆序对
- 《剑指offer》数组中的逆序对
- 【剑指offer】数组中的逆序对
- 剑指offer—数组中的逆序对
- 【剑指offer】之数组中的逆序对
- 剑指offer:数组中的逆序对
- [剑指offer]数组中的逆序对
- 剑指offer:数组中的逆序对
- 剑指Offer--036-数组中的逆序对
- [剑指offer]数组中的逆序对
- 《剑指offer》:[36]数组中的逆序对
- 《剑指offer》-数组中的逆序对
- 数组中的逆序对(剑指offer)
- Debian 环境下 vim编辑器 c语言代码高亮问题
- Java操作ElasticSearch之创建客户端连接
- window系统-禁用 Win+L快捷键
- Openwrt开发汇总
- 各大站长不可忽略的日常安全隐患
- 数组中的逆序对(剑指offer)
- java中几种常用的RPC框架介绍
- Java操作ElasticSearch之创建索引
- hdu 3367 Pseudoforest 变形最大生成树 解题报告
- 微信小程序 页面传值详解
- SVN安装(linux)
- Codeforces 808E Selling Souvenirs(花费是倍数关系的背包)
- java学习第28天,包装类,基本时间类
- android面试基础收集