4. 寻找两个正序数组的中位数(困难)

4. 寻找两个正序数组的中位数

 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 }

 

posted @ 2021-10-30 14:47  星予  阅读(33)  评论(0编辑  收藏  举报