1 class Solution {
2 public double findMedianSortedArrays(int[] nums1, int[] nums2) {
3 int n = nums1.length;
4 int m = nums2.length;
5
6 /**
7 * 如果 (n+m) 为奇数,比如3,那么 (n+m+1)/2 和 (n+m+2)/2 都等于 2。第2个数为中位数
8 * 如果 (n+m) 为偶数,比如4,那么 (n+m+1)/2 等于 2 而 (n+m+2)/2 等于 3。第2,3个数均值为中位数
9 */
10 int left = (n + m + 1) / 2;
11 int right = (n + m + 2) / 2;
12
13 return (getKth(nums1, 0 , n - 1, nums2, 0, m - 1, left) +
14 getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;
15 }
16
17 //该函数作用为:取两数组合并后第k小的数
18 //start与end为索引,k为求第k小数
19 public int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k){
20
21 //start与end为索引,索引0到1的长度为2(需要+1)
22 //len表示当前数组(或经过递归后的数组),没有被排除的元素的个数(长度)
23 int len1 = end1 - start1 + 1;
24 int len2 = end2 - start2 + 1;
25
26 //让 len1 的长度小于 len2,这样就能保证如果有数组空了,一定是 len1
27 //就是如果len1长度小于len2,把getKth()中参数互换位置,即原来的len2就变成了len1,即len1,永远比len2小
28 if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k);
29
30 //nums1中没有元素(全被排除),nums2再往后找k个数即为中位数
31 //start2没有被排除,例如nums2往后找1个数,从start2开始就是start2自己,下标start2 + 1 - 1不变
32 if (len1 == 0) return nums2[start2 + k - 1];
33
34 //k为1,离中位数只差1位,此时比较nums1与nums2的start即可
35 if (k == 1) return Math.min(nums1[start1], nums2[start2]);
36
37 //i,j存储目前打算排除的元素的右边界
38 //为了防止数组长度小于k/2,每次比较都会从当前数组所剩长度和k/2作比较,取其中的小的(如果取大的,数组就会越界)
39 int i = start1 + Math.min(len1, k / 2) - 1;
40 int j = start2 + Math.min(len2, k / 2) - 1;
41
42
43 //如果nums[i] > nums2[j],则nums2中包含j索引之前的元素全部淘汰,下次从j + 1开始
44 //而k变为k - (j - start2 + 1),即k减去排除的元素的个数
45 //j - start2后需要 + 1,因为索引相减,比如j = 3,start2 = 2,这两个都排除了,下次从4开始,实际排除了2个元素
46 if (nums1[i] > nums2[j]) {
47 return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));
48 }
49 else {
50 return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));
51 }
52
53 }
54 }