【35】数组中的逆序对
来源:互联网 发布:大拿韩代 知乎 编辑:程序博客网 时间:2024/06/05 18:14
【35】数组中的逆序对
时间限制:1秒
空间限制:32768K
本题知识点: 数组
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,
则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。
并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
输入例子:1,2,3,4,5,6,7,0 输出例子:7
牛客网题目链接:点击这里
方法一:两个for循环,时间复杂度n^2.
2016/9/6暴力解法已经无法通过测试,提示复杂度过高,运行超时
class Solution {public: int InversePairs(vector<int> data) { int count=0; if(data.empty()) return count; for(int i=0; i<data.size(); i++) { for(int j=i+1; j<data.size(); j++) { if(data[i]>data[j]) count++; } } return count; }};
方法二:从插入排序的角度考虑.
因为插入排序的交换次数就是逆序对的个数。但是插入排序的时间复杂度也是O(n^2).因此排除。
方法三:归并排序,从局部有序到整体有序
时间复杂度O(nlog(n)),稳定排序
算法代码:
class Solution { int merge_sort(vector<int> &data, int left, int right, vector<int> &temp) { if(left>=right) return 0; int sum=0; int center=(left+right)/2; sum+=merge_sort(data,left,center,temp); sum+=merge_sort(data,center+1,right,temp); int i=center,j=right; int p=right; while(i>=left && j>center) { if(data[i]>data[j]) { temp[p--]=data[i--]; sum=sum+(j-center); if(sum>1000000007) sum=sum%1000000007; //求余应该加在此处。 } else { temp[p--]=data[j--]; } } while(i>=left) { temp[p--]=data[i--]; } while(j>center) { temp[p--]=data[j--]; } for(int k=left; k<=right; k++) { data[k]=temp[k]; } return sum; }public: int InversePairs(vector<int> data) { //归并排序 vector<int> temp(data.size()); int result=0; result=merge_sort(data,0,data.size()-1,temp); return result; }};
说明:可以考虑辅助容器在merge函数内部开辟和取消
VS2010代码:
#include<iostream>#include<vector>using namespace std;class Solution {public: int InversePairs(vector<int> data) { if(data.empty()) return 0; int Num=0; //在不改变data的情况下,就需要对data进行复制操作 vector<int> dataCopy; dataCopy.resize(data.size()); for(int i=0; i!=data.size(); i++) { dataCopy[i]=data[i]; } //设置空的辅助数组 vector<int> Associate; Associate.resize(data.size()); Num=Mergesort(dataCopy, Associate, 0, dataCopy.size()-1 ); return Num; } //改进的归并排序 int Mergesort(vector<int> &Array, vector<int> &Associate, int begin, int end) { if(begin>=end) return 0; //定义该分组内的逆序对数 int count=0; int Mid=(begin+end)/2; count=count+Mergesort(Array, Associate, begin, Mid); count=count+Mergesort(Array, Associate, Mid+1, end); int p1=Mid,p2=end; int p3=end; while(begin<=p1 && Mid<p2) { if(Array[p1]>Array[p2]) { count=count+(p2-Mid); //程序逻辑正确,出现问题是因为把p2写成了end Associate[p3]=Array[p1]; p1--;p3--; } else {//题目中提示说不考虑相等的情况,因此这里为小于 Associate[p3]=Array[p2]; p2--;p3--; } } while(p1<begin && p2>Mid) //p1已完,p2还未复制完 { Associate[p3]=Array[p2]; p2--;p3--; } while(p1>=begin && p2==Mid) //p2已完,p1未完 { Associate[p3]=Array[p1]; p1--;p3--; } //将辅助数组中已排序好的元素赋给Array for(int i=begin;i<=end; i++) { Array[i]=Associate[i]; } return count; }};int main(){ Solution s1; vector<int> test1; test1.push_back(1); test1.push_back(2); test1.push_back(3); test1.push_back(4); test1.push_back(5); test1.push_back(6); test1.push_back(7); test1.push_back(0); //test1.push_back(7); //test1.push_back(5); //test1.push_back(6); //test1.push_back(4); cout<<s1.InversePairs(test1)<<endl; cout<<int(1000000007)<<endl; cout<<int(1000000007)<<endl;}
说明:
1.逻辑应该没有问题了,本地测试通过。
牛客网一直提示说:出现问题,请稍后重试。
0 0
- 【35】数组中的逆序对
- 35、数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 数组中的逆序对
- 解决某些手机日志被屏蔽的问题
- Java Basics Part 3/20 - Basic Syntax
- [交换机]POE交换机 - 简介
- POJ 2377Bad Cowtractors(并查集+Sort)
- POJ 1789 Truck History 最小生成树模板题
- 【35】数组中的逆序对
- HDU 1573 X问题
- 用realine库完善你的my_shell
- 《Apache Spark Graph Processing》中文版前4章下载
- 手写数字识别(2)---- CNN网络模型
- 数据结构实验之栈三:后缀式求值
- Google Code服务要关门了
- Tomcat热部署配置
- python读取文件时地址书写