字符串算法——两个有序数组的中位数
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个数。这里要考虑到两个数组长度之和是否是奇数还是偶数。
如果没有限制复杂度,可以采用归并计数法,这时的复杂度为O(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]); } } }
相关文章推荐
- 求两个等长有序数组的中位数的logN算法 分治法
- 求两个有序数组的中位数-算法导论
- 求两个等长有序数组的中位数的logN算法 分治法
- 求两个有序数组的中位数-算法导论
- 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
- 两个有序数组的中位数 【算法】
- 求两个等长有序数组的中位数的logN算法 分治法
- 算法基础 - 查找两个有序数组的中位数
- 求两个等长有序数组的中位数的logN算法 分治法
- 两个有序数组的中位数 【算法】
- 求两个等长有序数组中位数算法问题
- 给出两个长度为N的有序数组A和B 给出求中位数的算法
- 算法练习4.Median of Two Sorted Arrays两个有序数组的中位数(递归、分治)
- LeetCode 4. Median of Two Sorted Arrays 求两个有序数组的中位数
- (1.2.4.2)寻找两个有序数组中的第K个数或者中位数
- LeetCode 4. Median of Two Sorted Arrays(两个有序数组的中位数)
- 两个有序数组的中位数
- 求两个有序数组的中位数和者第k小元素
- 两个有序数组求解下中位数
- PHP 两个等长有序数组求合并后的中位数