어레이의 제 중앙값 [H가 2 개 개의 정렬 된 어레이 중간 정렬 두

이름

두 개의 정렬 된 배열이 있습니다 nums1nums2 각각 크기 m과 n의가.
두 개의 정렬 된 배열의 미디안을 찾습니다. 전체 실행 시간 복잡도는 O (로그 (m + N))이어야한다.
당신은 가정 할 수 nums1을 하고 nums2는 모두 비어있을 수 없습니다.
예 1 :
  nums1 = [1,3]
  nums2 = [2]
  의 중앙값은 2.0
예 2 :
  nums1 = [1, 2]
  nums2 = [3, 4]
  중앙값은 (2 + 3) = 2.5 /2.0

생각


이진 검색, 재귀

두 어레이 A를 가정하고 B의 수보다 \ (\ FRAC {K} { 2} \) 번호 (숫자 결함 배열 \ (\ FRAC {K} { 2} \) a) 각각 제 가라 \ (\ FRAC {K} { 2} \) 요소 (배열 $ \ FRAC {K} 라벨 {2 } - $ 1) 에 비해, 3 경우가됩니다 :

  • 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]

첫 번째 경우, 상기 제 1A의 경우, \ (\ FRAC {K}는 { 2} \) 요소 (어레이는 {2 $ \ FRAC {K} 표지 } -1- $) 섹션 B에보다 \ (\ FRAC을 {K} {2} \) 요소 (배열 첨자 \ (\는 K FRAC {-1} {2} \) ) 작고, A와 B는 나중에 합하고으로 설명하면 첨자 0 내지 ($ \ FRAC {K} {2} - \ 사이의 번호 (1) (k)의 다수의, 즉, 절단의 작은 배열 될 수 k는 그들이 동일한 경우 증가한다, (a (k)를 요소를 발견 할 필요가있다. -1 소자)의 경우보다 큰 홀수 중간 재귀 :. ** ** 1) 하나 개의 어레이는 상기 조건을 경계로 나누어 2.0 두 숫자 짝수 걸리지 유사하게 빈 다른 배열 첨자 [K-1]의 수에 직접적으로 반환한다. 2) K = 1, 즉 최소값 배열 (배열 첨자 0)의 처음 두 요소의 직접적인 비교를 찾는 경우 (k 번째 요소 상대 단일 어레이 참조). 3) A는 [\) 경우 \ K의 FRAC} {2} {- \ (1.] = B는 [\) \ K의 FRAC} {2} {-. $ 1], 그 중 하나가 리턴.


K-찾고 아이디어의 수를 잘라

통해 잘라 배열은 좌측 및 우측 부분으로 절단 : \ (파트 Left_ {}, {right_ 부품} \) ,이 때 생성 된 두 요소의 왼쪽에, 즉 최대 값 (\ L_ {최대} \) 와 오른쪽의 최소 값 \ (분 R_ {} \) . 절단 공정은 다수 잘라있다,이 번호는 모두 왼쪽에 속하는 권리 속해 컷은 두 숫자의 중간에있을 수있다.

  • 보고 단일 k 번째 소자 어레이
    K 개의 수가 순서 배열 A, 경우 (배열 첨자 K-1)의 리턴 값 절단 \ (A [K-. 1] = 최대 {L} \) , 즉을 (K)의 수, 좌측 부분의 최대 수. (K = 1, 2, ...)
  • 두 번 배열 첫 번째 케이 요소를 찾을 수

| \ (Left_ {부분} \) | \ (C_I \) | \ (Right_ {부분} \) |
| : --- : | : --- : | : --- : |
| \ (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 \) |

정의 (max_1 L_ {} \) \ , \ (max_2 L_ {} \) 컷오프 후 \ (Left_part \) 1 초 최대 어레이, \ (MIN_1 R_ {} \) , \ (R_ min_2 {}는 \) 컷 이후 \ (부품 right_ {} \) 1의 최소치 및 제 2 어레이. \ (C_1, C_2 \)은 컷의 제 1 및 제 2 어레이이다.
만약 만족 :
1). (\ max_1 L_ {} \ <\; R & LT MIN_1} {\) \ (max_2 L_ {} \ <\; min_2 R_ {} \) . (이 배열을 지시하기 때문에, 상기 좌우보다 작아야 만족해야한다.)
2) \ (max_1 L_ {} \ <= \; min_2 R_ {} \)\ (L_ {max_2} \] <= \; MIN_1 R_ {} \) . \ (Left_ {부분} \) 에 비해 전체 덜 \ (파트 right_ {} \) . 소자의 개수 K에 함께 정확히 동일두면 , 그 k 번째 원소 (\ 맥스 (L_ {} max_1 , L_ {max_2}) \)
(K 번째 요소를 찾기 위해 단일 어레이 참조). 만약 \ (max_1 L_ {} \;> \] min_2 R_ {} \) , 어레이 (1)의 여러 요소 (대) 감소 할 필요 왼쪽으로 설명 \을 (C_l \) 상기 (C_2 \) \ 커진다. 마찬가지로 가능 (max_2 L_ {} \;> \] MIN_1 R_ {} \) \ 하는 \는 (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