求两个不等长的有序数组的中位数
来源:互联网 发布:一淘和淘宝联盟返利高 编辑:程序博客网 时间:2024/05/07 14:04
网上的很多关于此题的做法都有Bug,故想了一下午,终于想到一个自我感觉Bug比较少的解法(可能还有Bug,欢迎大家指正)。
/** 求两个有序数组合并后的中位数,时间复杂度O(logn)*/#include <iostream>#include <string>using namespace std;/**1 2 3 4 5 6 7 8,此时left=right=5,表示如果一个数的右边有至少right个数,那么该数及左边都不是中位数对于奇数的话,统一起见*/void getMid(int *arr1, int n1, int *arr2, int n2){ int left = (n1+n2+1)/2+1; int right = left; int begin1 = 1; int begin2 = 1; int end1 = n1; int end2 = n2; bool flag = false; while(left!=2 || right!=2) { if(begin1>end1 || begin2>end2) //奇数时,中位数就一个,此时会出现这种情况 { flag = true; break; } int mid1 = (begin1+end1)/2; int mid2 = (begin2+end2)/2; int loffset = 0; int roffset = 0; if(arr1[mid1] == arr2[mid2]) { cout<<arr1[mid1]<<endl; } else if(arr1[mid1] < arr2[mid2]) { if(mid1-begin1+mid2-begin2+2 >= left) { roffset = end2 - mid2; if(roffset == 0 && right!=2) { if(arr2[end2] > arr1[end1]) { end2--; } else { end1--; } right--; continue; } } else { if(end2-mid2 > 1) { roffset = 1; } } if(end1-mid1+end2-mid2+2 >= right) { loffset = mid1 - begin1; if(loffset == 0 && left!=2) { if(arr1[begin1] < arr2[begin2]) { begin1++; } else { begin2++; } left--; continue; } } else { if(mid1-begin1 > 1) { loffset = 1; } } begin1 += loffset; end2 -= roffset; left -= loffset; right -= roffset; } else { if(end1-mid1+end2-mid2+2 >= right) { loffset = mid2 - begin2; if(loffset == 0 && left!=2) { if(arr1[begin1] < arr2[begin2]) { begin1++; } else { begin2++; } left--; continue; } } else { if(mid2-begin2 > 1) { loffset = 1; } } if(mid1-begin1+mid2-begin2+2 >= left) { roffset = end1 - mid1; if(roffset == 0 && right!=2) { if(arr2[end2] > arr1[end1]) { end2--; } else { end1--; } right--; continue; } } else { if(end1-mid1 > 1) { roffset = 1; } } begin2 += loffset; end1 -= roffset; left -= loffset; right -= roffset; } } if(flag) { if(begin1>end1) { for(int i=begin2+left-2; i<=end2-right+2; i++) { cout<<arr2[i]<<endl; } } else { for(int i=begin1+left-2; i<=end1-right+2; i++) { cout<<arr1[i]<<endl; } } return; } for(int i=begin1; i<=end1; i++) { cout<<arr1[i]<<endl; } for(int i=begin2; i<=end2; i++) { cout<<arr2[i]<<endl; }}int main(int argc,char* argv[]){ int arr1[]={0,1,3,6,8}; int arr2[]={0,2,4,5,7}; getMid(arr1, 4, arr2, 4); return 0;}
- 求两个不等长的有序数组的中位数
- 求两个等长有序数组的中位数
- 求两个等长有序数组的中位数
- 求两个不等长、有序数组的中位数非常简洁的O(log(min(M,N)))迭代解详细解释
- 两个等长有序数组求中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- Android 仿通讯录侧边栏滑动 SiderBar效果
- 在Android程序代码中实现软件安装和卸载
- 理解sparse coding
- JAVA基础之理解JNI原理
- hdu 4576 Robot (概率水题)
- 求两个不等长的有序数组的中位数
- 黑马程序员_.Net操作Excel(DataGridView导入导出Excel)
- Cocos2d-x 多分辨率适配完全解析
- 位操作基础篇之位操作全面总结
- Android 4.1 设置默认开机动态壁纸
- HDU 1024 最大m段子段和 Max Sum Plus Plus
- HDU 1195 Open the Lock
- 12-预编译执行dql语句
- Linux内核编译过程详解 | 流星雪