Title description:
Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.
Follow up: The overall run time complexity should be O(log (m+n)).
Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
Example 3:
Input: nums1 = [0,0], nums2 = [0,0]
Output: 0.00000
Example 4:
Input: nums1 = [], nums2 = [1]
Output: 1.00000
Example 5:
Input: nums1 = [2], nums2 = []
Output: 2.00000
Constraints:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
Time complexity: O(log (m+n))
Binary Search Dichotomy:
Given two ordered arrays, find the median (n + m) / 2, which is equivalent to finding the k-th smallest element, k = ( n + m) / 2
- When the total length len is an even number, the median is the average of the len/2th smallest number and the len/2 + 1st smallest number.
- When the total length len is an odd number, the median is the len/2 + 1th smallest number.
The question becomes how to find the k-th smallest number in two ordered arrays. We first take the first k/2 elements from nums1 and nums2.
- If the k/2th decimal of the first array nums1 is greater than the k/2th decimal of the second array nums2, that is: nums1[k/2−1]> nums2[k/2−1]. It means that the first k/2 elements in nums2 must be less than the kth smallest number. So we can take out these numbers first, and then find the k−⌊k/2⌋ decimal in the remaining numbers.
- Similarly, if the k/2th decimal of the first array nums1 is smaller than the k/2th decimal of the second array nums2, that is, nums1[k/2−1] <nums2[k/2−1]. It means that the first k/2 elements in nums1 must be less than the k-th smallest number. So we can take out these numbers first, and then find the k−⌊k/2⌋ decimal in the remaining numbers.
Consider the boundary conditions:
- If the total length of any array is less than k/2, for example, the length of nums1 is n <k/2. You need to consider the effective length of each array and the effective length of the array nums1 (starting point is i) effective length si = Math.min(nums1.length, i+k/2); The
effective length of the array nums2 (starting point is j) sj = j + k-k/2. - When nums1[si-1]> nums2[sj-1], it means that the k-th smallest number of target must be in [i,n] and [sj,m]
- When nums1[si-1] <= nums2[sj-1], it means that the k-th smallest number of target must be in [si,n] and [j,m]
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len = nums1.length + nums2.length;
if(len%2 == 0){
int left = find(nums1, 0, nums2, 0, len/2);
int right = find(nums1, 0, nums2, 0, len/2+1);
return (left+right)/2.0;
}else{
return (double)find(nums1, 0, nums2, 0, len/2+1);
}
}
int find(int[] nums1, int i, int[] nums2, int j, int k){
//默认第一个是小的
if(nums1.length - i > nums2.length-j){
return find(nums2, j, nums1, i, k);
}
if(nums1.length == i){
return nums2[j+k-1];
}
//当取第1个元素
if(k == 1) return Math.min(nums1[i],nums2[j]);
int si = Math.min(nums1.length, i+k/2);
int sj = j+k-k/2;
if(nums1[si-1] > nums2[sj-1]){
return find(nums1, i, nums2, sj, k-(sj-j));
}else{
return find(nums1, si, nums2, j, k-(si-i));
}
}
}