分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)
来源:互联网 发布:淘宝信欣美妆靠谱吗 编辑:程序博客网 时间:2024/05/17 21:52
思路:
分治法 归并排序的过程中,有一步是从左右两个数组中,每次都取出小的那个元素放到tmp[]数组中
右边的数组其实就是原数组中位于右侧的元素。当不取左侧的元素而取右侧的元素时,说明左侧剩下的元素均比右侧的第一个元素大,即均能构成一个逆序对。假设现在左侧剩余n个元素,则逆序对数+n。
另外,如果当所有右侧的元素都取完,但是左侧仍然有元素剩余时,左侧剩余的元素已经在之前的运算中加到了逆序对中,不需要再添加一次
下面给出 归并排序 和 求逆序对数 两份代码:
code1:
归并排序
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n;int a[20];void query(int a[], int first, int mid, int last, int tmp[]){ int i = first, j = mid+1; int k = 0; while(i <= mid && j <= last){ if(a[i] < a[j]) tmp[k++] = a[i++]; else tmp[k++] = a[j++]; } while(i <= mid){ tmp[k++] = a[i++]; } while(j <= last){ tmp[k++] = a[j++]; } for(int id = 0; id < k; id++){ a[first + id] = tmp[id]; }}void merge_sort(int* a, int L, int R, int* tmp){ if(L < R){ int M = L + (R-L)/2; merge_sort(a,L,M,tmp); merge_sort(a,M+1,R,tmp); query(a,L,M,R,tmp); }}int main(){ scanf("%d",&n); for(int i = 0; i < n; i++){ scanf("%d",&a[i]); } int tmp[20]; merge_sort(a,0,n-1,tmp); for(int i = 0; i < n; i++){ printf("%d ",a[i]); } printf("\n"); return 0;}
code2:
求逆序对数:
cnt 表示逆序对数的个数
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n;int a[20];int cnt;void query(int a[], int first, int mid, int last, int tmp[]){ int i = first, j = mid+1; int k = 0; while(i <= mid && j <= last){ if(a[i] <= a[j]) tmp[k++] = a[i++]; else{ tmp[k++] = a[j++]; cnt += mid-i+1; } } while(i <= mid){ tmp[k++] = a[i++]; } while(j <= last){ tmp[k++] = a[j++]; } for(int id = 0; id < k; id++){ a[first + id] = tmp[id]; }}void merge_sort(int* a, int L, int R, int* tmp){ if(L < R){ int M = L + (R-L)/2; merge_sort(a,L,M,tmp); merge_sort(a,M+1,R,tmp); query(a,L,M,R,tmp); }}int main(){ scanf("%d",&n); for(int i = 0; i < n; i++){ scanf("%d",&a[i]); } int tmp[20]; cnt = 0; merge_sort(a,0,n-1,tmp); for(int i = 0; i < n; i++){ printf("%d ",a[i]); } printf("cnt = %d\n",cnt); printf("\n"); return 0;}
LRJ给的代码不好理解....
0 0
- 分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)
- 用分治法求最大子序列问题,时间复杂度O(N*logN)
- 分治法 时间为logn的求x^n的算法
- O(logN)时间复杂度内求整数的N次方以及矩阵的N次方
- 求两个有序序列的中位数。(要求时间复杂度为O(logN))
- [逆序数]用归并排序求逆序数。时间复杂度(n*logn)
- 求逆序对数的一种时间复杂度为nlgn的算法
- O(logn)时间复杂度求Fibonacci数列
- O(logn)时间复杂度求Fibonacci数列
- O(logn)时间复杂度求Fibonacci数列
- O(logn)时间复杂度求Fibonacci数列
- 分治法求逆序对数
- 求一个数组的中位数时间复杂度为O(n)
- 给定无序自然数数组,求最大连续自然数个数,时间复杂度为O(n)
- 给定无序自然数数组,求最大连续自然数个数,时间复杂度为O(n)
- 分治 求逆序对数
- 算法时间复杂度的白话解析----logN,N,N*logN
- 求n很大时求,<= n的素数的个数(时间复杂度o(n ^ 2 / 3)模板
- 宏展开中遇到意外的文件结束
- iOS设计模式之三:MVC模式
- 在Mac OS下中下载与安装jdk
- POJ 1141 Brackets Sequence
- 贪心算法设计 之最少硬币数目
- 分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)
- Spring MVC对比Struts2
- mac xcode运行opengl
- LeetCode #Longest Substring Without Repeating Characters#
- 阿里巴巴2016实习生招聘编程题
- NYOJ Yougth的最大化
- sysobjects 表结构
- c语言004---预处理
- 2016阿里实习线上笔试题-附加题1-随机数生成器