第一个hard题。
我第一想法是合并排序,nlogn
对于这个题,时间复杂度应该是o(m+n)log(m+n),而不是题目要求的o(Log(m+n))
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int i=0,j=0,k=0;
int m=nums1.length;
int n=nums2.length;
int[] a=new int[m+n] ;
for(i=0,j=0,k=0;i<m&&j<n;k++){
if(nums1[i]<=nums2[j]){
a[k]=nums1[i++];
}
else{
a[k]=nums2[j++];
}
}
if(j==n){
while(i<m){
a[k++]=nums1[i++];
}
}
if(i==m){
while(j<n){
a[k++]=nums2[j++];
}
}
int count=k;
int mid=count/2;
//特别要注意某一数组为空,另一数组只有一个,合并后数组只有一个元素的情形
//加上mid>0的限制条件,否则mid-1会越界的
if(count%2==0&&mid>0){
return (a[mid-1]+a[mid])*0.5;
}
else
return a[mid]*1.0;
}
}
这是很经典的一道题目!!!
帮助我理解划分的思路:
https://blog.csdn.net/hk2291976/article/details/51107778
https://www.jianshu.com/p/9bd57fd52062
这道题是找中位数,扩展为找第中间个大的数。这样整个合并的数组就要分奇偶讨论。
长度为偶数要找第(len1+len2)/2大的数和第((len1+len2)/2 )+1大的数
长度为奇数,找第((len1+len2)/2 )+1 大的数
设p是nums1的第p大的数,q是nums2的第q大的数(q=k-p),这样讨论nums1[start1+p-1]和num2[start2+q-1]就能得到“合并”的第k大的数。
要求划分后nums1,nums2的左半部分都比nums1,nums2的右半部分要小,如果不行,就不停移动nums1的i来划分。
采用二分搜索算法,就是分治法中取2(其实取3,4,5,6都行,就是碰运气吗),取2的话最经典,时间复杂度是logn
class Solution {
public double findMedianSortedArrays(int[] A, int[] B) {
int m = A.length;
int n = B.length;
if (m > n) { // 强制规定nums1是短的那个
int[] temp = A; A = B; B = temp;
int tmp = m; m = n; n = tmp;
}
int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2; //相当于取p,每次取p都是二分法
int j = halfLen - i; //相当于是q
if (i < iMax && B[j-1] > A[i]){ //要让划分的左边都小于右边
iMin = i + 1; // i is too small
}
else if (i > iMin && A[i-1] > B[j]) {
iMax = i - 1; // i is too big
}
else { // i is perfect
int maxLeft = 0;
if (i == 0) { maxLeft = B[j-1]; }
else if (j == 0) { maxLeft = A[i-1]; }
else { maxLeft = Math.max(A[i-1], B[j-1]); }
if ( (m + n) % 2 == 1 ) { return maxLeft; } //合并数组长为奇数,就是 第(m + n + 1) / 2个大的数
//合并数组长为偶数,就是 第(m + n + 1) / 2个大的数和第(m + n + 1) / 2 +1个大的数
int minRight = 0;
if (i == m) { minRight = B[j]; }
else if (j == n) { minRight = A[i]; }
else { minRight = Math.min(B[j], A[i]); }
return (maxLeft + minRight) / 2.0;
}
}
return 0.0;
}
}
扩展找第k个大的数的化,就是分治的思想啦
https://www.jianshu.com/p/9bd57fd52062