4. Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

You may assume nums1 and nums2 cannot be both empty.

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5


第一种方法:只讨论m + n 为奇数的情况(偶数基本相同),则我们要找出一个数v满足在nums1,nums2 所有比v小的个数为less_num =(m + n + 1) / 2 个, 设start1, end1为nums1 需要考察的区间
start2, end2为nums2需要考察的区间, 每次考察(end1 - start1 + 1) = (end2 - start2 + 1) = ceil(less_num / 2).如果nums1[end1] < nums2[end2] 则 我们要的值不可能出现在
nums1区间[start1, end1]中, 更新less_num -= (end - start + 1), start1 = end1 + 1, end1 = start1 + ceil(less_num / 2) - 1, start2 不变,
end2 = start2 + ceil(less_num / 2) - 1. 以此类推nums2[end2] < nums1[end1]的情况, 每次less_num都减半,直到less_num = 0找到所求, 时间复杂度为o(log(m + n))
 1 class Solution {
 2     
 3     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
 4         int m = nums1.length, n = nums2.length;
 5         int mid = (m + n) / 2 + (m + n) % 2;
 6         int pos1 = -1, pos2 = -1;
 7         while (mid > 0) {
 8             int temp = mid / 2 + mid % 2;
 9             if (pos2 + temp >= n || 
10                 (pos1 + temp < m && nums1[pos1 + temp] < nums2[pos2 + temp])) {
11                 pos1 += temp;
12             } else {
13                 pos2 += temp;
14             }
15             mid -= temp;
16         }
17         
18         
19         
20         double ans = 0;
21         if (pos2 == -1 || (pos1 != -1 && nums1[pos1] >= nums2[pos2])) {
22             ans = nums1[pos1];
23         } else {
24             ans = nums2[pos2];
25         }
26         if ((m + n) % 2 == 0) {
27             double  temp;
28             if (pos2 + 1 >= n || 
29                 (pos1 + 1 < m && nums1[pos1 + 1] < nums2[pos2 + 1]))
30                 temp = nums1[pos1 + 1];
31             else {
32                 temp = nums2[pos2 + 1];
33             }
34             ans = (ans + temp) / 2 ;
35         }
36         return ans;
37         
38     }
39 }
View Code

  第二种方法为solution中的做法,我就简单用自己的语言说说

首先把两个数组分成两个集合

          left_part          |        right_part
    A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]
    B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]
假设m + n 是偶数,我们的目标就是找出满足 i + j = m - i + n - j(即两个集合元素个数相同), left_part最大的元素maxleft <= minright(right_part最小的元素)的 i 和 j,
找出以后 求出maxleft 和minright (maxleft + minright) / 2 为所求中位数
下面两份代码,第一份是自己看一遍题解写出的代码,第二份是学习题解代码写的代码。
 1 class Solution {
 2     
 3     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
 4         if (nums1.length > nums2.length) {
 5             int []temp = nums1;
 6             nums1 = nums2;
 7             nums2 = temp;
 8         }
 9         
10         int m = nums1.length, n = nums2.length;
11         if (m == 0) {
12             if (n % 2 == 1) {
13                 return nums2[n / 2];
14             } else {
15                 return (nums2[n / 2 - 1] + nums2[n / 2]) / 2.0;
16             }
17         }
18         int l = 0, r = m, i = 0, j;
19         while (l < r) {
20             i = (l + r) / 2;
21             j = (m + n) / 2 - i;
22             
23             if (i < m && nums2[j - 1] > nums1[i]) {
24                 l = i + 1;
25                 i = i + 1;
26                 continue;
27             }
28             if (i > 0 && nums1[i - 1] > nums2[j]) {
29                 r = i - 1;
30                 i = i - 1;
31                 continue;
32             }
33             break;
34         }
35         
36         j = (m + n) / 2 - i;
37         double ans = 0;
38         if ((m + n) % 2 == 1) {
39             if (i == m) {
40                 ans = nums2[j];
41             } else if (j == n) {
42                 ans = nums1[i];
43             } else {
44                 ans = Math.min(nums1[i], nums2[j]);
45             }
46             
47         } else {
48             System.out.println(i);
49             if (i == 0) {
50                 if (j == n) ans = (nums2[j - 1] + nums1[i]) / 2.0; 
51                 else ans = (nums2[j - 1] + Math.min(nums1[i], nums2[j])) / 2.0 ;
52             } else if (j == 0) {
53                 System.out.println((nums1[i - 1] + nums2[j]) / 2.0);
54                 if (i == m) ans = (nums1[i - 1] + nums2[j]) / 2.0;
55                 else ans = (nums1[i - 1] + Math.min(nums1[i], nums2[j])) / 2.0;
56             } else {
57                 ans = Math.max(nums1[i - 1], nums2[j - 1]);
58                 double temp;
59                 if (i == m) {
60                     temp = nums2[j];
61                 } else if (j == n) {
62                     temp = nums1[i];
63                 } else {
64                     temp = Math.min(nums1[i], nums2[j]);
65                 }
66                 ans = (ans + temp) / 2.0;
67             }
68         }
69         return ans;
70         
71     }
72 }
View Code
 1 class Solution {
 2     
 3     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
 4         if (nums1.length > nums2.length) {
 5             int []temp = nums1;
 6             nums1 = nums2;
 7             nums2 = temp;
 8         }
 9         
10         int m = nums1.length, n = nums2.length;
11         
12         int l = 0, r = m, i = 0, j;
13         while (l <= r) {
14             i = (l + r) / 2;
15             j = (m + n) / 2 - i;
16             
17             if (i < r && nums2[j - 1] > nums1[i]) {
18                 l = i + 1;
19                 
20             } else if (i > l && nums1[i - 1] > nums2[j]) {
21                 r = i - 1;
22                 
23             } else {
24                 
25                 int minright = 0;
26                 if (i == m) {
27                     minright = nums2[j];
28                 } else if (j == n) {
29                     minright = nums1[i];
30                 } else {
31                     minright = Math.min(nums1[i], nums2[j]);
32                 }
33                 if ((m + n) % 2 == 1) return minright;
34                 
35                 int maxleft = 0;
36                 if (i == 0) {
37                    
38                     maxleft = nums2[j - 1];
39                 } else if (j == 0) {
40                     maxleft = nums1[i - 1];
41                 } else {
42                     
43                     maxleft = Math.max(nums1[i - 1], nums2[j - 1]);
44                 }
45                 
46                 return (maxleft + minright) / 2.0;
47             }
48             
49         }
50         
51         return 0.0;
52     
53         
54         
55        
56         
57     }
58 }
View Code
原文地址:https://www.cnblogs.com/hyxsolitude/p/12231538.html