题目:
4. Median of Two Sorted Arrays(hard)
解题思路:
看到时间复杂度O(log(m+n)),看到log就想到二分。
借鉴选取第k小数的的解法,每次在两个数组中查找第k/2个数,比较大小后,去掉不可能是第k小的前若干数,直到一个数组查找完或直接在两数开头比较。
参考题解
代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
int left = (n + m + 1) / 2;
int right = (n + m + 2) / 2;
//将奇偶情况合并,如果是奇数,会求两次同样的k
return (getKth(nums1,0,n-1,nums2,0,m-1,left) + getKth(nums1,0,n-1,nums2,0,m-1,right)) * 0.5;
}
private int getKth(int[] nums1,int s1,int e1,int[] nums2,int s2,int e2,int k){
int len1 = e1 - s1 + 1;
int len2 = e2 - s2 + 1;
//让len1的长度小于len2,这样就能保证如果有数组空了,一定是len1
if(len1 > len2) return getKth(nums2,s2,e2,nums1,s1,e1,k);
//递归出口
//如果小数组先结束了,直接去大数组中取第k-1个数
if(len1 == 0) return nums2[s2 + k - 1];
//取第k个数时,若k等于1,则直接从两数开头取较小值
if(k == 1) return Math.min(nums1[s1],nums2[s2]);
//防止数组长度小于k/2,每次比较min(len,k/2)较小那个
int i = s1 + Math.min(len1,k/2) - 1;
int j = s2 + Math.min(len2,k/2) - 1;
//去掉前面那些不可能是中位数的数字
if(nums1[i] > nums2[j]){
return getKth(nums1,s1,e1,nums2,j+1,e2,k - (j - s2 + 1));
}else{
return getKth(nums1,i+1,e1,nums2,s2,e2,k - (i - s1 + 1));
}
}