Daily leetcode - 4 Find the median of two positively ordered arrays

Posted by Blue Blood on Fri, 04 Mar 2022 19:55:35 +0100

subject

Give two positively ordered (from small to large) arrays of size m and n, \\\\\\\\. Please find and return the median of these two positive arrays.

The time complexity of the algorithm should be O(log (m+n)).

Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
 Explanation: merge arrays = [1,2,3] ,Median 2

Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
 Explanation: merge arrays = [1,2,3,4] ,median (2 + 3) / 2 = 2.5

Merge sort

Using the idea of merging and sorting, set two pointers at the beginning of two arrays, compare the size of the two pointers, and move backward until the median is found.

The time complexity of this method is O(m+n), which can not meet the requirements of the problem, and the code considering the boundary condition is complex.

dichotomy

The idea of dichotomy: the median of a positive array is the number with the smallest k in the array. For example, if the array length is 7, the median is the fourth number.
Find the median and convert it into finding the k-th number.
Split the array into two positive order arrays, that is, find the k/2 number in the two arrays respectively.

If the K / 2nd number of array A is less than the K / 2nd number of array b, the fraction from the starting position to the K / 2nd position in array a can be excluded, and the median must not be in these numbers
Because if the median is among these numbers, the most extreme case is that the k/2 number of a is the median, then the first k/2 number of array b should be less than it.
But in fact, the k/2 number of b is greater than the k/2 number of a, so the assumption is not tenable
Therefore, the party with the smaller number of k/2 must not have the median.

Several points for attention:

  1. The number of k decreases in each cycle is determined by the number of excluded numbers, rather than directly halving.
  2. Boundary of search range:
    If the end range exceeds the array range, go to the end of the array as the end range
    If the starting range exceeds the array range, it means that the array is empty. Go directly to another array to check the remaining k numbers

    For example, there are two arrays:
    A: 1 3 4 9
    B: 1 2 3 4 5 6 7 8 9
    
    The lengths of the two ordered arrays are 4 and 9 respectively, and the sum of the lengths is 13,
    The median is the seventh element in the entire array, so you need to find the second element k=7 A small number.
    
    Let's find the third smallest number in the two arrays:
    A: 1 3 4 9
        ↑
    B: 1 2 3 4 5 6 7 8 9
        ↑
    A The third smallest number is 4, B The third smallest number is 3
    B The third small<A From the third small, we can draw a conclusion:
    The seventh smallest number we are looking for must not be here B Of the top three
     Because if the seventh smallest number is B Of the top three, the most extreme case is B 3 in is the seventh smallest number
     The first six numbers of the seventh smallest number will not be greater than it, B 2 numbers in front of 3 are less than 3, and the remaining 4 numbers should be A in
     however A There are only 2 numbers in which there are no more than 3
    
    Therefore, the 7th smallest number we are looking for must not be here B Of the top three, you can B The first three numbers are excluded
     At this time, looking for the 7th smallest number, three of them have been excluded, leaving four
     In the two arrays, find the second smallest number respectively
    A: 1 3 4 9
      ↑
    B: [1 2 3] 4 5 6 7 8 9
              ↑
    A The second smallest number is 3, B The second smallest number is 5
     Ibid., the seventh smallest number must not be A Exclude these two numbers from the first two numbers
    
    Look for the 7th smallest number. Three numbers have been excluded, and now two are excluded. There are still two numbers left
     In the two arrays, find the first smallest number respectively
    A: [1 3] 4 9
          ↑
    B: [1 2 3] 4 5 6 7 8 9
            ↑
    A The first smallest number is 4, B The first smallest number is also 4, which is equal
     In this case, we regard it as A<B Dispose of A This number, B Immobility
    
    There is only one number left. At this time, directly compare the first number of the non excluded parts of the two arrays,
    The smaller number is the seventh smallest number
    A: [1 3 4] 9
            ↑
    B: [1 2 3] 4 5 6 7 8 9
            ↑
    The seventh smallest number is B So the median of the two positive arrays is 4
    def findMedianSortedArrays(nums1, nums2):
     def getTheKNum(k):
         # Both pointers are initially at the position of 0
         start1,start2 = 0,0
         # Start of cycle two
         while True:
             # 4. When start has moved to the last + 1 position of the array, it indicates that the array is empty. Go to another array to check the remaining k numbers
             if start1==m:
                 return nums2[start2+k-1]
             if start2==n:
                 return nums1[start1+k-1]
             
             # 5. When k is excluded to 1, directly compare the number of start positions of the two arrays. The smaller one is the median
             if k==1:
                 return min(nums1[start1],nums2[start2])
             
             # 1. Determine the number of [theoretically] two arrays to view according to the value of k
             halfK = k//2
             
             # 2. Determine the position of end: start from start and check whether the number of halfk s will exceed the array range
             # Start is the index, so there are start+1 numbers at start
             # Starting from start, check the number of halfks. Since the number of start positions is included, it is the number of halfks-1
             # Therefore, start from start to check the number of halfk, a total of start+1+halfk-1=start+halfk
             # Whether it exceeds the length range len (Num) of the array itself. If it exceeds, locate end to the end of the array. If it does not exceed, it is normal
             # end = min(start+halfk,len)-1
             end1 = min(start1+halfK,len(nums1))-1
             end2 = min(start2+halfK,len(nums2))-1
             
             # 3. After determining how many numbers to view, start comparing the number of end positions
             # Small, exclude this score, recalculate the k value, and move start
             if nums1[end1] <= nums2[end2]:
                 k = k - (end1-start1+1)
                 start1 = end1+1
             else:
                 k = k - (end2-start2+1)
                 start2 = end2+1
                 
     m,n = len(nums1),len(nums2)
     totalLen = m+n
     if totalLen%2 == 1:
         return getTheKNum(totalLen//2+1)
     else:
         return ((getTheKNum(totalLen//2))+(getTheKNum(totalLen//2+1)))/2

Topics: data structure