这道题,根据时间复杂度的要求可以想到是利用mid值,但是怎么利用,还有就是奇偶的不同,我觉得还是人家的办法好,也就是这里的第二种办法。
题目如下:
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。
请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。
示例 1:
nums1 = [1, 3]
nums2 = [2]
中位数是 2.0
我的笨方法:32ms
package test;
public class LC4Try1
{
public double findMedianSortedArrays(int[] nums1, int[] nums2)
{
double ret = 0;
int l1=nums1.length;
int l2=nums2.length;
int count=(l1+l2)/2;
//tag就是标签,决定取一位还是两位//所以我这个并不好,人家的只是找一个,我这个还是分情况
int tag=(l1+l2)%2;
ret=getpass(nums1,nums2,0,l1,0,l2,count,tag);
return ret;
}
public double getpass(int[] nums1, int[] nums2, int s1, int e1, int s2,
int e2,int count,int tag)
{
double ret;
if(s1==e1){
if(tag==0){
ret=(nums2[s2+count-1]+nums2[s2+count])/2.0;
}else{
ret=nums2[s2+count];
}
return ret;
}
if(s2==e2){
if(tag==0){
ret=(nums1[s1+count-1]+nums1[s1+count])/2.0;
}else{
ret=nums1[s1+count];
}
return ret;
}
if(count==1){
if(tag==0){
int min1=nums1[s1];
int min2=nums2[s2];
if(s1+1<e1){
min2=Math.min(min2, nums1[s1+1]);
}
if(s2+1<e2){
min1=Math.min(min1, nums2[s2+1]);
}
//ret取的是第一小和第二小值
ret=(min1+min2)/2.0;
}else{
int max1=Math.max(nums1[s1], nums2[s2]);
if(s1+1<e1){
max1=Math.min(max1, nums1[s1+1]);
}
if(s2+1<e2){
max1=Math.min(max1, nums2[s2+1]);
}
//ret取的第二小值
ret=max1/1.0;
}
return ret;
}
int len=Math.min(e1-s1, e2-s2);
len=Math.min(len, count/2);
count=count-len;
if(nums1[s1+len-1]<=nums2[s2+len-1]){
ret=getpass(nums1,nums2,s1+len,e1,s2,e2,count,tag);
}else{
ret=getpass(nums1,nums2,s1,e1,s2+len,e2,count,tag);
}
return ret;
}
public static void main(String[] args)
{
LC4Try1 t = new LC4Try1();
int[] nums1={2,3,4};
int[] nums2={1};
System.out.println(t.findMedianSortedArrays(nums1, nums2));
}
}
较好的办法:29ms
package test;
//喜欢
public class LC4Try2
{
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int l = (nums1.length + nums2.length + 1) / 2;
int r = (nums1.length + nums2.length + 2) / 2;
return (findKth(nums1, 0, nums2, 0, l) + findKth(nums1, 0, nums2, 0, r)) / 2.0;
}
public double findKth(int[] A, int aStart, int[] B, int bStart, int k) {
if (aStart >= A.length) return B[bStart + k - 1];
if (bStart >= B.length) return A[aStart + k - 1];
if (k == 1) return Math.min(A[aStart], B[bStart]);
int aMid = Integer.MAX_VALUE;
int bMid = Integer.MAX_VALUE;
if (aStart + k/2 - 1 < A.length) aMid = A[aStart + k/2 - 1];
if (bStart + k/2 - 1 < B.length) bMid = B[bStart + k/2 - 1];
if (aMid < bMid) {
return findKth(A, aStart + k/2, B, bStart, k - k/2);
} else {
return findKth(A, aStart, B, bStart + k/2, k - k/2);
}
}
}
哈哈