标签:col 一个 额外 查找 span 中位数 保存 swa nbsp
1.实践题目:两个有序序列的中位数
2.问题描述:
输入一个n(0<N<=1e5),代表两个有序序列的长度,随后两行分别键入两个非降序序列,求出两个序列的合并后的中位数,此处中位数指有序序列中的第(N+1)/2个数,下标从0开始。
3.算法描述:
创建两个数组a,b用来保存两个有序序列,设定四个下标al,ar,bl,br用来表示两个序列的左下标和右下标,先比较两个原始序列的中位数,对在两个中位数上下界之间的序列进行递归查找(注意在查找的过程中需要让划分出的子序列长度相等,故需在计算中间下标时+1),不断缩小查找的范围,直到最后剩余四个数为止。对剩余四个数进行简单的排序(本题采用冒泡排序),取出中间的两个数作最后一次除法,返回答案即可。
部分代码如下:
1 int solve(int al, int ar, int bl, int br){ 2 int ans; 3 if((al+1 == ar || al == ar) && (bl+1 == br || bl == br)){ 4 int num[4] = {a[al], a[ar], b[bl], b[br]}; 5 for(int i=0;i<4;i++){ 6 for(int j=0;j<3-i;j++){ 7 if(num[j]>num[j+1]) swap(num[j+1],num[j]);//冒泡排序 8 } 9 } 10 int mid = (num[1] + num[2]) / 2;//求取最终答案 11 return mid; 12 } 13 int am = (al + ar+1) >> 1;//划分子表 14 int bm = (bl + br) >> 1; 15 if(a[am] > b[bm]) 16 ans = solve(al, am, bm, br); 17 else 18 ans = solve(am, ar, bl, bm); 19 return ans;//返回答案 20 }
4.算法分析
时间复杂度:该算法在每步将问题分成规模均为N/2的1个子问题,在划分操作时,复杂度为O(1),在合并的操作中,4个数的冒泡排序及简单的运算的时间复杂度可看做O(1)级别,故可根据定义式得出算法的时间复杂度为O(logn)。
空间复杂度:存储两个序列时,消耗了2n个单元的空间,递归时的额外开销不计的话,空间复杂度为O(n)。
5.心得体会
其实自己之前在处理递归问题的时候不太有头绪,在思考这道题的时候,队友提出的这个方法法让人眼前一亮。虽然不太确定中位数是否具备上述所言的这么些特点,但是在用代码实现并通过之后也可以认为这个算法是正确的。通过完成这道题,让我对递归的理解进一步加深,也学会了一种求解中位数的算法。
标签:col 一个 额外 查找 span 中位数 保存 swa nbsp
原文地址:https://www.cnblogs.com/Benboys/p/9824688.html