两种方法求解逆序对
来源:互联网 发布:rrt算法 编辑:程序博客网 时间:2024/05/21 19:36
逆序对定义:对于一个包含N个非负整数的数组A[1..n],如果有i < j,且A[ i ]>A[ j ],则称(A[ i] ,A[ j] )为数组A中的一个逆序对。
常见的两种方法求解逆序对:1.穷举法(暴力求解),时间复杂度O(n^2)。2.归并法, 时间复杂度O(nlogn)。
穷举法:对于一个给定的序列,依次从左往右取每一个元素,从该元素右边第一个元素开始向右扫描,遇到比它小的元素,则计数+1,直到处理完整个序列。
#include <iostream>#include <cstdlib>#include <cstdio>using namespace std;#define MAXN 1000int num[MAXN];int sum = 0;void solve(int n){ for(int i = 0; i < n; i++) for(int j = i+1; j < n; j++) { if(num[i] > num[j]) sum++; }} int main(int argc, char const *argv[]){ int n; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &num[i]); solve(n); printf("%d\n", sum); return 0;}
归并法:将序列A[l..r]分成两半A[l..mid]和A[mid+1..r]分别进行归并排序,然后再将这两半合并起来。
在合并的过程中(设l<=i<=mid,mid+1<=j<=r),当A[i]<=A[j]时,不产生逆序数;当A[i]>A[j]时,在
前半部分中比A[i]大的数都比A[j]大,所以,将A[j]放在A[i]前面的话,逆序数要加上mid+1-i。因此,可以在归并排序中的合并过程中计算逆序数。
#include <iostream>#include <cstdlib>#include <cstdio>using namespace std;#define MAXN 1000int num[MAXN], temp[MAXN];int sum = 0;void Merge(int l, int mid, int r){ int i = l, j = mid+1, k = l; while(i <= mid && j <= r) { if(num[i] > num[j]) { temp[k++] = num[j++]; sum += mid-i+1;//产生逆序对 } else temp[k++] = num[i++]; } while(i <= mid) temp[k++] = num[i++]; while(j <= r) temp[k++] = num[j++]; for(int i = l; i <= r; i++) num[i] = temp[i];}void Merge_sort(int l, int r){ if(l < r) { int mid = l + (r-l)/2;//可防止加法溢出 Merge_sort(l, mid);//左边 Merge_sort(mid+1, r);//右边 Merge(l, mid, r);//合并 }} int main(int argc, char const *argv[]){ int n; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &num[i]); Merge_sort(0, n-1); printf("%d\n", sum); return 0;}
附上POJ逆序对的一道测试题:http://poj.org/problem?id=1804
0 0
- 两种方法求解逆序对
- 归并排序,树状数组 两种方法求逆序对
- 求解逆序对
- 逆序对的求解
- 两种方法求单链表逆序
- 求解逆序对数的几种方法
- Minimum_Window_Substring两种方法求解
- 求解数组中的逆序对
- 求逆序对数的两种方法
- 单链表反转/逆序的两种方法
- 单链表反转/逆序的两种方法
- 单链表反转/逆序的两种方法
- 单链表反转/逆序的两种方法
- 单链表反序,逆序的两种方法
- 水仙花数(armstrong)求解,两种方法
- 最小二乘法求解的两种表示方法
- 两种方法求解Fibonacci数列
- N!的位数两种方法求解
- MySQL中的多表查询
- 计蒜客 硬币翻转(二进制压缩)
- LeNet5的基本结构
- 题目29
- 《DO圣堂刺客2》国服首测今天拉开
- 两种方法求解逆序对
- java内存区域理解-初步了解
- 三种静态查找的思路及具体实现
- javascript笔试题(3)
- Ceph剖析:数据分布之CRUSH算法与一致性Hash
- C 二级指针和三级指针的使用
- python 中 list 列表 的十种操作方法:添加,插入,弹出,删除,延长,运算,查找,排序,反转,采用递归函数深度遍历list
- 题目34
- MySQL中的一些常用的函数