4. Медиана Массивы [Н] Два Сортирована два отсортированных массив медианы

титульный

Есть два отсортированных массивов nums1 и nums2 размера т и п соответственно.
Найти мадианитянин двух отсортированных массивов. Общая сложность время работы должно быть O (журнал (т + п)).
Можно считать nums1 и nums2 не могут быть пустыми.
Пример1:
  nums1 = [1, 3]
  nums2 = [2]
  Медиана 2,0
Пример 2 :
  nums1 = [1, 2]
  nums2 = [3, 4]
  Медиана (2 + 3) /2.0 = 2,5

мышление


Двоичный поиск, рекурсия

Предположим , что два массивов А и В больше , чем число \ (\ гидроразрыва {к} { 2} \) номер (ряд недостатков массива \ (\ гидроразрыва {к} { 2} \) а), соответственно, Возьмите первый \ (\ гидроразрыва {k} { 2} \) элементов (массив меченого $ \ гидроразрыва {k} {2 } - $ 1) сравниваются, и есть три случая:

  • А [$ \ гидроразрыва {к} {2} - $ 1] \ (\; \) < \ (\; \) В [$ \ гидроразрыва {к} {2} - $ 1]
  • А [$ \ гидроразрыва {к} {2} - $ 1] \ (\; \) = \ (\; \) В [$ \ гидроразрыва {к} {2} - $ 1]
  • А [$ \ гидроразрыва {к} {2} - $ 1] \ (\; \) > \ (\; \) В [$ \ гидроразрыва {к} {2} - $ 1]

В первом случае, если первый А \ (\ гидроразрыва {к} { 2} \) элементов (массив помечены $ \ гидроразрыва {K} {2 } -1 $) , чем сечение B \ (\ гидроразрыва {к} {2} \) элементов (индекс массива \ (\ к FRAC {-1} {2} \) ) мал, когда а и в , описанных позже были объединены, индекс а от 0 до ($ \ гидроразрыва {к} {2} - число между \ (1) не может быть большое число к, то есть небольшой массив разреза, к должно быть увеличено , если они равны, является необходимость найти элементы (а к. -1 элементы) больше , чем в случае с нечетным номером аналогично взять меньше , чем в середине, четное число двух чисел делящихся от 2,0 до граничных условий рекурсивной ** :. ** 1) , где один массив пусто, возвращается непосредственно в другой индекс массива [K-1] число. (См один массив Глядя к-го элемента) 2) Если к = 1, то есть , чтобы найти минимальное значение, прямое сравнение двух первых элементов массива (массив индексом 0) до. 3) Если А [\) \ К FRAC} {2} {- \ (1.] = В [\) \ К FRAC} {2} {-. $ 1], только один из них вернулся.

подсказки


Обрежьте число к-ищет идеи

Прорубленный, массив разрезают на левую и правую части: \ (Часть Left_ {}, {right_ Часть} \) , два элемента , генерируемые в это время, а именно максимальное значение левого \ (L_ {макс} \) , а минимальное на правой значение \ (мин R_ {} \) . Процесс может Вырезать Вырезать число, то это число принадлежит как левая и правая принадлежит; Вырезать может также быть в середине двух чисел.

  • Одно к-й элемент массива ищет
    для упорядоченного массива А, в к числу (массив индекс к-1) разрезать на возвращаемое значение \ (A [к-. 1] = тах {L} \) , а именно число к, максимальное количество левой части. (К = 1,2, ...)
  • Дважды массив найти первые к элементам

| \ (Left_ {часть} \) | \ (C_i \) | \ (Right_ {часть} \) |
| : ---: | ---: | ---: |
| \ (a_1, a_2, \ cdots, a_i \) | / | \ (а_ {+ 1}, {а_ г + 2}, \ cdots, a_m \) |
| \ (b_1, b_2, \ cdots, b_j \) | / | \ (b_ {j + 1}, b_ {j + 2}, \ cdots, a_n \) |

Определить (max_1 L_ {} \) \ , \ (max_2 L_ {} \) после Вырезать \ (Left_part \) максимум 1 секунду и массив, \ (MIN_1 R_ {} \) , \ (R_ {min_2} \) после Вырезать \ (часть right_ {} \) минимальным значением 1 и второго массива. \ (C_1, C_2 \) является первым и вторым массивом Cut.
Если удовлетворены:
1). \ (Max_1 L_ {} \; <\, R & MIN_1 л} {\) , \ (max_2 L_ {} \; <\; min_2 R_ {} \) . (Это должно быть выполнено, так как упорядоченный массив, должен быть меньше , чем слева направо.)
2) \ (max_1 L_ {} \; <= \; min_2 R_ {} \) и \ (L_ {max_2} \; <= \; MIN_1 R_ {} \) .
В \ (Left_ {часть} \) Полный меньше , чем \ (часть right_ {} \) . Если число элементов вышли вместе в точности равен к , то к-й элемент \ (макс (L_ {max_1} , {L_ max_2}) \)(См один массив , чтобы найти к - го элемента). Если \ (max_1 L_ {} \;> \; min_2 R_ {} \) , многие элементы массива 1 , описанный левый (большой), необходимость уменьшения \ (C_l \) , то (C_2 \) \ возрастает. Точно так же доступны (max_2 L_ {} \;> \; MIN_1 R_ {} \) \ , A \ (C_l \) увеличивается, \ (C_2 \) уменьшается.

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];
        }
    }  
};

питон

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           

ссылка

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

рекомендация

отwww.cnblogs.com/Jessey-Ge/p/10991587.html