アレイの4中央値[H] 2つのソート2つのソート配列メジアン

タイトル

2つのソート列がありnums1nums2それぞれサイズmとnのは。
2つのソート配列のミディアンを検索します。全体的な実行時間の複雑さはO(ログ(M + N))であるべきです。
あなたは、想定し得るnums1をしてnums2は両方とも空にすることはできません。
例1:
  nums1 = [1,3]
  nums2 = [2]
  の中央値が2.0である
例2:
  nums1 = [1、2]
  nums2 = [3、4]
  の中央値は、(2 + 3)/2.0 = 2.5

考え


バイナリ検索、再帰

2つの配列Aを仮定し、Bは数よりも大きい\(\ FRAC {K} { 2} \) 番号(数欠陥のアレイ\(\ FRAC {K} { 2} \) a)に、それぞれ、最初取る\(\ FRAC {K} { 2} \) の要素(アレイが$ \ FRAC {K}標識{2 } - $ 1) と比較し、そして3例がありされました:

  • [$ \ FRAC {K} {2} - $ 1] \(\; \) < \(\; \) B [$ \ FRAC {K} {2} - $ 1]
  • [$ \ FRAC {K} {2} - $ 1] \(\; \) = \(\; \) B [$ \ FRAC {K} {2} - $ 1]
  • [$ \ FRAC {K} {2} - $ 1] \(\; \) > \(\; \) B [$ \ FRAC {K} {2} - $ 1]

最初のケースでは、第1のA、場合\(\ FRAC {K} { 2} \) の要素(配列$ \ FRAC {K} {2標識 } -1 $)をセクションBのより\(\ FRAC {K} {2} \)の要素(配列添字\(\ K FRAC {-1} {2} \) 小さな、及びBは、後述する場合を合わせ、0から添字A $ \(へFRAC {K} {2} - \の間の数(1)kの多数、すなわち、カットの小さいアレイにすることはできませんそれらが等しい場合、kは増加されるべきであるが、要素(Kを見つける必要があります。 -1の要素)の再帰的境界条件に2.0で割る2つの数の偶数、奇数中間未満を取るために、同様の場合よりも大きい** :. ** 1)つのアレイである、請求あります空のは、別の配列の添字[K-1]の数に直接戻ります。2)ここで、k = 1、すなわち、最小値、アレイ(配列添字0)の最初の2つの要素の直接比較を見つけることと(k番目の要素探して単一の配列を参照)。3)\)場合 \ KのFRAC} {2} { - \(1] = Bは[\) \ KのFRAC} {2} { - $ 1]、それらの一方のみが返されます。

ヒント


K-探しているアイデアの数をカット

カットスルー、アレイは、左と右の部分に切断されている:\(そのLeft_ {}、{right_パート} \) この時点で生成された二つの要素は、左のの、すなわち最大値\(L_ {最大} \) 右側に最小値\(MIN R_ {} \) 切断プロセスは番号をカットすることができる、この数は、左右属する両方に属し、切断は、2つの数値の中間にあってもよいです。

  • 見て単一のk番目の要素の配列
    戻り値で切断k個(配列添え字K-1)で順序付けられた配列Aのため\([K-1] =最大{L} \) すなわち、 kの数、左側部分の最大数。(K = 1,2、...)
  • ダブル配列は、最初のk個の要素を見つけます

| \(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の最小値と二番目の配列。\(C_1、C_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番目の要素である(MAX(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
おすすめ