4. Median of Arrays [H] Two Sorted two sorted array median

topic

There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the midian 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.
Example1:
  nums1 = [1, 3]
  nums2 = [2]
  The median is 2.0
Example2:
  nums1 = [1, 2]
  nums2 = [3, 4]
  The median is (2+3)/2.0 = 2.5

Thinking


Binary search, recursion

Suppose two arrays A and B is greater than the number \ (\ frac {k} { 2} \) number (a number of deficiencies array \ (\ frac {k} { 2} \) a), respectively, Take the first \ (\ frac {k} { 2} \) elements (array labeled $ \ frac {k} {2 } - $ 1) are compared, and there are three cases:

  • A[$\frac{k}{2}-$1] \(\;\)< \(\;\) B[$\frac{k}{2}-$1]
  • A[$\frac{k}{2}-$1] \(\;\)=\(\;\) B[$\frac{k}{2}-$1]
  • A[$\frac{k}{2}-$1] \(\;\)>\(\;\) B[$\frac{k}{2}-$1]

In the first case, if the first A, \ (\ frac {k} { 2} \) elements (array labeled $ \ frac {k} {2 } -1 $) than the section B \ (\ FRAC {k} {2} \) elements (array subscript \ (\ K FRAC {-1} {2} \) ) small, when a and B described later were combined, subscript a from 0 to ($ \ frac {k} {2} - number between \ (1) can not be a large number of k, i.e., a small array of cut, k should be increased if they are equal, is the need to find elements (a k. -1 elements) is larger than the case of the odd-numbered similarly to take less than the middle, an even number of the two numbers dividing by 2.0 to boundary conditions recursive **:. ** 1) wherein one array is empty, returns directly to another array subscript [k-1] number. (See single array Looking k-th element) 2) If k = 1, i.e. to find a minimum value, a direct comparison of the first two elements of the array (array subscript 0) to. 3) If A [\) \ K FRAC} {2} {- \ (. 1] = B [\) \ K FRAC} {2} {- $. 1], only one of them returned.

Tips


Cut the number of k-looking ideas

Cut through, the array is cut into left and right parts: \ (Part Left_ {}, {right_ Part} \) , two elements generated at this time, namely the maximum value of the left \ (L_ {max} \) and the minimum on the right value \ (min R_ {} \) . Cut process may Cut a number, then this number belongs to both the left and the right belongs; Cut may also be in the middle of two numbers.

  • Single k-th element array looking
    for an ordered array A, in the k number (the array subscript k-1) cut at the return value \ (A [k-. 1] = max {L} \) , namely the number of k, the maximum number of left-hand portion. (k = 1,2, ...)
  • Double-Array find the first k elements

| \(Left_{part}\) | \(C_i\) | \(Right_{part}\) |
| :---: |: --- :|: --- :|
|\(a_1,a_2,\cdots,a_i\) | / | \(a_{i+1},a_{i+2},\cdots,a_m\)|
|\(b_1,b_2,\cdots,b_j\) | / | \(b_{j+1},b_{j+2},\cdots,a_n\)|

Define (max_1 L_ {} \) \ , \ (max_2 L_ {} \) is after Cut \ (Left_part \) a maximum of 1 second and the array, \ (MIN_1 R_ {} \) , \ (R_ {min_2} \) is after Cut \ (Part right_ {} \) minimum value of 1 and the second array. \ (C_1, C_2 \) is the first and second array of Cut.
If satisfied:
. 1) \ (max_1 L_ {} \; <\; R & lt MIN_1} {\) , \ (max_2 L_ {} \; <\; min_2 R_ {} \) . (This must be satisfied, because an ordered array, must be smaller than the left to the right.)
2) \ (max_1 L_ {} \; <= \; min_2 R_ {} \) , and \ (L_ {max_2} \; <= \; MIN_1 R_ {} \) .
The \ (Left_ {part} \) Full less than \ (Part right_ {} \) . If the number of elements left together exactly equal to k , then the k-th element is \ (Max (L_ {max_1} , L_ {max_2}) \)(See single array to find the k th element). If \ (max_1 L_ {} \;> \; min_2 R_ {} \) , many elements of the array 1 described left (large), the need to reduce \ (C_l \) , the (C_2 \) \ increases. Similarly available (max_2 L_ {} \;> \; MIN_1 R_ {} \) \ , a \ (C_l \) is increased, \ (C_2 \) decreases.

C++

class Solution {
public:
     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
         
         int n1 = nums1.size();
         int n2 = nums2.size();    
         int total = n1 + n2;
         
         if(total % 2){ //如果数组加起来是奇数 
             return findKth(nums1, 0, nums2, 0, total / 2 + 1);
         }
         else{ //如果是偶数
             return (findKth(nums1, 0, nums2, 0, total / 2 ) + findKth(nums1, 0, nums2, 0, total / 2 + 1) )/2.0;
         }
           
     }
    
    //分割的思想寻找第k个数
    double findKth(vector<int>& nums1, int l, vector<int>& nums2, int r, int k){
        
        int n1 = nums1.size();
        int n2 = nums2.size();
        
        if(n1 - l > n2 -r ) 
              return findKth(nums2, r, nums1, l, k); //始终保证第一个数组是个数是最少的
        
        if(n1-l == 0)
            return nums2[r + k -1];
        if(k == 1)
            return min(nums1[l], nums2[r]);
        
        int p1 = min(k/2 , n1); //保证在第一个数组内做二分查找。
        int p2 = k - p1;
        
        if(nums1[l + p1 -1] < nums2[r + p2 -1]){ //左边
            return findKth(nums1, l+p1,nums2, r,k - p1);
        }
        else if(nums1[l + p1 -1] > nums2[r + p2 -1]){ //左边数组1的个数太大
            return findKth(nums1, l,nums2, r+p2,k - p2);
        }
        else{
            return nums1[l+p1-1];
        }
    }  
};

python

class Solution(object):
    def findKth(self, nums1, nums2,k):
        
        k = int(k)
        n1 = len(nums1)
        n2 = len(nums2)
        
        if n1 > n2: 
            return self.findKth(nums2, nums1, k)
        if n1 == 0: 
            return nums2[k - 1]
        if k == 1: 
            return min(nums1[0], nums2[0])
        p1 = int(min(k / 2, n1))
        p2 = k - p1
        if nums1[p1 - 1] <= nums2[p2 - 1]:
            return self.findKth(nums1[p1:], nums2, p2)
        else:
            return self.findKth(nums1, nums2[p2:], p1)
        
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        n1 = len(nums1)
        n2 = len(nums2)
        total = n1 + n2
        if(total % 2):
            return self.findKth(nums1, nums2, total /2 + 1)
        else:
            return (self.findKth(nums1, nums2, total /2 )+ self.findKth(nums1, nums2, total /2 + 1))/2.0           

reference

[1] https://blog.csdn.net/hk2291976/article/details/51107778
[2] https://leetcode.com/problems/median-of-two-sorted-arrays/solution/

Guess you like

Origin www.cnblogs.com/Jessey-Ge/p/10991587.html