Title: give two one-dimensional int arrays a and B. where: A is an ordered array with length m and elements in good order from small to large. B is an ordered array with length n and elements arranged from small to large. We hope to find the maximum k numbers from the A and B arrays. It is required to use as few comparisons as possible.
Solution:
1. Firstly, the concept of upper median (algorithm prototype) is introduced
When writing the function to judge the upper median, first ensure that the lengths of the two arrays are the same.
1.1 when the length of two arrays is even
eg: arr1 = {a,b,c,d}; arr2 = {e,f,g,h}, find the fourth largest number
- When b==f, b and F are the upper median
- When B < f When, abe is less than f, so the first three smallest numbers include ab; gh is greater than f, that is, gh is greater than abef, so gh is certainly not the fourth largest number, so the fourth largest number can only be generated in cd and ef, so recursively find the upper median in cdef.
- When b > F Similarly, the fourth largest number can be obtained only in ab and gh Generated in, so recursively find abgh Upper median.
1.2 when both array lengths are odd
eg: arr1 = {a,b,c,d,e}; arr2 = {f,g,h,i,j}, find the 5th largest number
- When c==h, c and H are the upper median
- When c < h, abc is less than h and fg is less than h, so hij must be the number after the fifth digit, so only consider whether abc and fg meet the requirements. However, the recursive solution cannot be performed at this time, because the lengths of the two arrays are not equal, so it is necessary to manually judge the relationship between c and g
- c==g: c, G are the upper median
- C < G: abc is three of the first four small numbers, so the fifth largest number can only be in de And fg, so recursively find the upper median in defg.
- c > G: abfg is less than c, and c is the upper median
- When C > H: the solution is the same as 2
2. Problem solving
There are different ways to solve the k parameter in the k-th largest number. Suppose that the length of array A is 10 and the length of array B is 15
eg: Note: the number in the array only represents the position, not the value
arr1 = {1,2,3,4,5,6,7,8,9,10} arr1.length = len1
arr2 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} arr2.length = len2
2.1 When 1 < = k < = 10 (1 < = k < = len1), assume k=6
Because k=6, < len1 & & < len2, the sixth smallest number can only appear in the first six numbers of the two arrays.
So we just need to call the function to find the upper median and pass in the first six digits of the two arrays
2.2 when 10 < K < 15 (len1 < K < len2), assume k=12
Because k=12, all numbers in arr1 are possible. In array arr2, 1 (the largest number is the 11th number) and 13-15 (the smallest number is 13-15) are impossible. Therefore, 2-12, a total of 11 numbers, meet the conditions, while the first array is 10 numbers. The lengths of the two arrays are different and the function number cannot be called. Therefore, it is necessary to manually judge a number, that is, 2 in arr2
- Arr2 [2] > = Arr1 [10]: arr[2] is the 12th number
- Arr2 [2] < Arr1 [10]: the maximum number of arr[2] is the 11th. If it does not meet the requirements, it will be eliminated. Solve arr1[1-10],arr2[3-12]
After solving the upper median (the tenth) plus the two eliminated, it is exactly the twelfth number
2.3 when 15 < = k < = 25 (len2 < = k), assume k=20
Because k=20, the numbers before arr2[10] do not meet the requirements (when all elements in arr1 are pressed before arr2[10], arr2[10] can reach the 20th number, and the previous ones do not meet the requirements). Similarly, find out the ones that meet the conditions in arr1, that is
arr1[5]-arr1[10],arr2[10]-arr2[15], but when only the upper median of the two arrays is calculated, it will be found that 4 + 9 = 13 numbers have been eliminated before, and the median 6 = 19, not 20. Therefore, before calculating the upper median, it is necessary to judge whether the leftmost elements of the two arrays meet the requirements
- arr1[5] > arr2 [15]: return to arr1[5]
- arr2[10] > Arr1 [10]: return to arr2[10]
- If they are not satisfied, solve arr1[6]-arr1[10],arr2[11]-arr2[15]
At this time, arr1 eliminated 5 numbers, arr2 eliminated 10 numbers, and the median 5 is exactly the 20th number
3 Coding
public static int findKthNum(int[] arr1, int[] arr2, int kth) { if (arr1 == null || arr2 == null) { throw new RuntimeException("Your arr is invalid!"); } if (kth < 1 || kth > arr1.length + arr2.length) { throw new RuntimeException("K is invalid!"); } //Copy long array int[] longs = arr1.length >= arr2.length ? arr1 : arr2; //Copy short array int[] shorts = arr1.length < arr2.length ? arr1 : arr2; int l = longs.length; int s = shorts.length; //k is less than the short array length if (kth <= s) { return getUpMedian(shorts, 0, kth - 1, longs, 0, kth - 1); } //k is greater than the length of the long array if (kth > l) { //Determine whether the leftmost element of the short array that meets the condition is the desired element if (shorts[kth - l - 1] >= longs[l - 1]) { return shorts[kth - l - 1]; } //Determine whether the leftmost element of the long array that meets the conditions is the desired element if (longs[kth - s - 1] >= shorts[s - 1]) { return longs[kth - s - 1]; } //Find the upper median return getUpMedian(shorts, kth - l, s - 1, longs, kth - s, l - 1); } if (longs[kth - s - 1] >= shorts[s - 1]) { return longs[kth - s - 1]; } return getUpMedian(shorts, 0, s - 1, longs, kth - s, kth - 1); } //To find the upper median, ensure that the two arrays are the same length public static int getUpMedian(int[] a1, int s1, int e1, int[] a2, int s2, int e2) { int mid1 = 0; int mid2 = 0; int offset = 0; while (s1 < e1) { mid1 = (s1 + e1) / 2; mid2 = (s2 + e2) / 2; offset = ((e1 - s1 + 1) & 1) ^ 1; if (a1[mid1] > a2[mid2]) { e1 = mid1; s2 = mid2 + offset; } else if (a1[mid1] < a2[mid2]) { s1 = mid1 + offset; e2 = mid2; } else { return a1[mid1]; } } return Math.min(a1[s1], a2[s2]); }