Give two positively ordered (from small to large) arrays of sizes m and n nums1 and nums2. Please find and return the median of these two positive arrays.
Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merge array = [1,2,3], median 2
Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4], median (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
1. Own solution: make middle=(length1+length2)/2. To find the median, you need to divide it into two cases: the total number of array elements is odd and even. If it is an odd number, the median is the largest number in the middle; If it is an even number, the median is the average of the sum of the number with the largest middle and the number with the largest middle+1. That is, the problem finally becomes to find the number with the largest middle and the largest middle+1 in the two arrays, so write a function to find the number with the largest K.
Find the K / 2nd number in two arrays A and B, namely A[K/2-1] and B[K/2-1]. At this time, compare the size of these two numbers in three cases:
① A [K/2-1] < B [K/2-1], then it indicates that the first K/2 elements in a cannot be the k-th number. Exclude these numbers,
Continue to look in the remaining elements.
②A[K/2-1] > B[K/2-1], then it means that the first k / 2 elements in B cannot be the k-th number. Exclude these numbers,
Continue to look in the remaining elements.
③A[K/2-1] = B[K/2-1], which can be classified into the first case.
You can use recursion. Pay attention to the update of K after excluding elements every time, and the update of the new starting subscript of the two arrays should be very detailed. Also note that the K-th largest subscript is K-1. Recursion can also be changed to a loop.
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int length1 = nums1.length; int length2 = nums2.length; int totalLength = length1 + length2; int middleIndex = (length1 + length2)/2; if(totalLength % 2 == 1){//Cases where the total number is odd return getKthNumber(nums1,nums2,middleIndex + 1,0,0); }else{//Cases where the total number is even return (double)(getKthNumber(nums1,nums2,middleIndex,0,0) + getKthNumber(nums1,nums2,middleIndex + 1,0,0)) / 2; } } //Find the k-th largest number in two arrays public int getKthNumber(int[] nums1,int[] nums2,int k,int index1,int index2){ int length1 = nums1.length; int length2 = nums2.length; //Boundary condition if(index1 == length1){//When the first array has no remaining elements return nums2[index2 + k - 1]; } if(index2 == length2){//When the second array has no remaining elements return nums1[index1 + k - 1]; } if(k == 1){//When k is equal to 1, you can directly compare the first of the remaining elements of the two arrays return Math.min(nums1[index1],nums2[index2]); } //Other normal conditions int half = k/2; int newIndex1 = Math.min(length1,half + index1) - 1;//Determine whether the array subscript will be out of bounds int newIndex2 = Math.min(length2,half + index2) - 1; if(nums1[newIndex1] <= nums2[newIndex2]){ return getKthNumber(nums1,nums2,k - (newIndex1 - index1 + 1),newIndex1 + 1,index2);//Update the remaining k and the new array start subscript }else{ return getKthNumber(nums1,nums2,k - (newIndex2 - index2 + 1),index1,newIndex2 + 1); } } }
2. Other solutions. See a person using a small skill, here also post it (from the comment @ Wait). We can find the (m+n+1) / 2 and (m+n+2) / 2 respectively, and then find their average value, which is applicable to odd and even numbers. If m+n is an odd number, then the values of (m+n+1) / 2 and (m+n+2) / 2 are equal, which is equivalent to adding two identical numbers and dividing them by 2, or itself.
His code and its brevity:
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int m = nums1.length; int n = nums2.length; int left = (m + n + 1) / 2; int right = (m + n + 2) / 2; return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0; } //i: Start position of nums1 J: start position of nums2 public int findKth(int[] nums1, int i, int[] nums2, int j, int k){ if( i >= nums1.length) return nums2[j + k - 1];//nums1 is an empty array if( j >= nums2.length) return nums1[i + k - 1];//nums2 is an empty array if(k == 1){ return Math.min(nums1[i], nums2[j]); } int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE; int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE; if(midVal1 < midVal2){ return findKth(nums1, i + k / 2, nums2, j , k - k / 2); }else{ return findKth(nums1, i, nums2, j + k / 2 , k - k / 2); } } }
It is mainly to learn the skills of not distinguishing parity.
Question source: Force buckle