多数组中位数

来源:互联网 发布:湖南软件职业学院 电话 编辑:程序博客网 时间:2024/04/29 22:57
给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数。
例如:
arr1 = {1,2,3,4};
arr2 = {3,4,5,6};
一共8个数则上中位数是第4个数,所以返回3。

arr1 = {0,1,2};
arr2 = {3,4,5};
一共6个数则上中位数是第3个数,所以返回2。

要求:时间复杂度O(logN)

解析:

首先求中位数,我们可以将两个数组合并成一个数组然后排序求中位数 但是这是不可取的 因为无论是快排还是插入排序平均时间最好是nlogn

根据题目要求我们发现 我们不必将两个数组完全排序完成只需要得到前n个数即可求出中位数  如何快速得到前n个有序的数?

我们发现将两个数组合并成一个数组这个过程就是归并排序的第二步可以利用归并排序得到中位数

方法一:

时间复杂度n

关键代码:

for (int i = 0;i<arr1.size();i++){    if (arr1[index1]<=arr2[index2]){        mid = arr1[index1];        index1++;    }else{        mid = arr2[index2];        index2++;    }}

方法二:


第一种情况:

arr1 = {1,2,3,4};  low1=0数组1的起点位置    high1=arr1.length 数组1的尾点位置 
arr2 = {1,2,5,6};  low2=0数组2的起点位置    high2=arr1.length 数组2的尾点位置 

中位数是合并后数组的第四个数 

mid1 = 2 数组1中位数将数组      mid2 = 2 数组2中位数

mid1=mid2

合并后mid1就是整个数组的中位数


第二种情况:

当n为偶数时:

arr1 = {1,2,3,4};  low1=0     high1=arr1.length 
arr2 = {3,4,5,6};  low2=0     high2=arr1.length  

中位数是第四个数 mid1 = 2        mid2 = 4  

mid2>mid1   mid2后面的数不可能数中位数 mid1前面的数不可能是中位数 排除

数组变成:

arr1 = {3,4}; low1=2  high1=arr1.length  low1=mid1的下标+1  high1=不变
arr2 = {3,4}; low2=0   high2=1                low1=不变  high1=mid2

mid1 = 3     mid2 = 3

mid1=mid2 

合并后mid1就是整个数组的中位数


当n为奇数时:

arr1 = {0,1,2};
arr2 = {3,4,5};

中位数是第四个数 mid1 = 1        mid2 = 4  

mid2>mid1   mid2后面的数不可能数中位数 mid1前面的数不可能是中位数 排除

数组变成:

arr1 = {1,2}; low1=1  high1=arr1.length  即low1=mid1的下标  high1=不变
arr2 = {3,4}; low2=0   high2=1                即low1=不变  high1=mid2

mid1 = 1     mid2 = 3

mid2>mid1   mid2后面的数不可能数中位数 mid1前面的数不可能是中位数 排除

数组变成:

arr1 = {2}; 
arr2 = {3};                 

结束循环 比较小的即为中位数

在循环的过程中要始终保持arr1与arr2长度相等

时间复杂度logn

代码:

public int getUpMedian(int[] arr1, int[] arr2) {    int low1 = 0;    int high1 = arr1.length-1;    int low2 = 0;    int high2 = high1;    while(low1<high1&&low2<high2){        int mid1 = low1 + ((high1-low1)>>1);        int mid2 = low2 + ((high2-low2)>>1);        if (arr1[mid1]==arr2[mid2]){            return arr1[mid1];        }        if (arr1[mid1]<arr2[mid2]){            if ((((high1-low1)+1)&1)==0){//判断奇偶 偶数加一个                low1 = mid1+1;            }else {                low1 = mid1;            }            high2 = mid2;        }else {            if ((((high1-low1)+1)&1)==0){                low2 = mid2+1;            }else {                low2 = mid2;            }            high1 = mid1;         }    }    return arr1[low1]>arr2[low2]?arr2[low2]:arr1[low1];}
题目来源:http://www.nowcoder.com/practice/c001f4e9820447189110da5e882aa158?rp=4&ru=/activity/oj&qru=/ta/2016test/question-ranking

0 0
原创粉丝点击