您的位置:首页 > 其它

字符串算法——两个有序数组的中位数

2017-10-12 08:25 344 查看
问题:有两个有序的数组nums1和nums2,长度分别为m和n,找到两个有序数组的中位数,运行时间复杂度为O(log(m+n))

例如:

nums1 = [1,3],nums2 = [2],中位数为2.0

nums1 = [1,2],nums2 = [3,4],中位数为2.5

解决思路:如果没有要求时间复杂度,可以对两个数组的每个元素依次比较排序或者使用归并排序,这里要求时间复杂度为O(log(m+n))则可以采用对两个数组同时采用二分法来确定中位数。可以将求解中位数转化为求解两个有序数组中的第K个数,则中位数为第(m+n)/2个数。这里要考虑到两个数组长度之和是否是奇数还是偶数。

class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int k = (m+n+1)/2;//第k个数
if((m+n)%2==0){//长度为偶数情况
return (findKth(nums1,nums2,0,0,m,n,k)+findKth(nums1,nums2,0,0,m,n,k+1))/2;
}else{
return findKth(nums1,nums2,0,0,m,n,k);//奇数情况
}
}
private double findKth(int[]arr1,int[]arr2,int start1,int start2,int len1,int len2,int k){
if(len1>len2){//保证数组1的长度小于数组2
return findKth(arr2,arr1,start2,start1,len2,len1,k);
}
if(len1==0){//当数组1长度为0
return arr2[start2+k-1];
}
if(k == 1){//如果k为1,返回两个数组的最小值
return Math.min(arr1[start1],arr2[start2]);
}
//将k分为数组1的p1范围和数组2的p2范围
int p1 = Math.min(k/2,len1);
int p2 = k-p1;
//判断k是落在哪个区间范围
if(arr1[start1+p1-1]<arr2[start2+p2-1]){
return findKth(arr1,arr2,start1+p1,start2,len1-p1,len2,k-p1);
}else if(arr1[start1+p1-1]>arr2[start2+p2-1]){
return findKth(arr1,arr2,start1,start2+p2,len1,len2-p2,k-p2);
}else{
return arr1[start1+p1-1];
}
}


如果没有限制复杂度,可以采用归并计数法,这时的复杂度为O(n)

class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums2.length;
int m = nums1.length;
int total = m+n;
if(total%2==0){//长度为偶数
return (findKthFei(nums1,nums2,total/2)+findKthFei(nums1,nums2,total/2+1))/2.0;
}else{//为奇数时
return findKthFei(nums1,nums2,total/2+1);
}

}
private double findKthFei(int[]arr1,int[]arr2,int k){
int p = 0,q = 0;//两个指针,指向数组底部,比较指针大小
//判断k的范围
for(int i = 0;i<k-1;i++){
if(p>=arr1.length && q<arr2.length){
q++;
}else if(q>=arr2.length && p<arr1.length){
p++;
}else if(arr1[p]>arr2[q]){
q++;
}else{
p++;
}
}
if(p>=arr1.length){
return arr2[q];
}else if(q>=arr2.length){
return arr1[p];
}else{
return Math.min(arr1[p],arr2[q]);
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息