最適解O(ログ(MIN(M、N)))
/ * * (+ N + 1(M規則的な配列と組み合わせて考える前作らO )/ 2)、 今でO(ログ(のmin(m、しよう n個))) 基本的な考え方は次のとおりです。バイナリよりも、検索中央値は、(ルーチンの最後の境界が存在すると仮定して)小の対応するアレイ得る 、それぞれN1、N2を想定し、N1 <= N2、2つの仮定は、最終的に中央値M1、M2番号ことを見出してもよいしなければなりません(または存在すると仮定) 、バイナリ探索nums1、初期値は右= N1 = 0を去ったとき、m1がある[0、N1]、M2が有する[K-N1は、N1]( K-N1 = 0>が必ずしも成り立ちます) そして、N1 <= n2と、そう確かに[N2、0]の間平方メートル、そのためだけの治療0と特別な事情のN1、N2の終わりに、クロスボーダー心配する事の小さな配列を横断する必要はありません。 ** * / クラスソリューション{ パブリック: ダブル findMedianSortedArrays(ベクトル< INT >&nums1、ベクトル< INT >&nums2){ // まず、第1のアレイの後小さい、大きいアレイであるかどうかを検出する のconst int型 N1 = nums1.size(); constの 整数 N2 =nums2.size(); もし(N1> N2)の戻りfindMedianSortedArrays(nums2、nums1)。 int型M1、M2; intは =左の0を、右= N1、K =(N1 + N2 + 1)/ 2 。 // 二分查找M1、M2(假设存在) 、一方(左< 右){ M1 =左+(左右)/ 2 。 M2 = K- M1; もし(nums1 [M1] <nums2 [M2- 1 ]) 左 =のM1 + 1 。 他に 右 =のM1; } M1 = ;左 M2 - = K- M1; int型、C1、C2 // 合計が奇数である場合、第1の数C1を見つけるには、戻り C1 = MAX(M1 <= 0 INT_MIN:nums1 [?ML- 。1 ]、 M2 <= 0 INT_MIN:nums2 [?M2- 1 ]); IF((N1 + N2)&1。 == 1 ) 戻りC1; //は、第2の数C2を見つけ、戻る(C1 + C2)/ 2 C2分=(M1> N1 = INT_MAX:nums1 [M1]、M2> = N2 ?? INT_MAX:nums2 [M2]); 戻り ダブル(C1 + C2)* 0.5 ; } }。
方法2:規則的な配列をマージ
O(ログ(M + N + 1)/ 2)
クラス解決{ パブリック: ダブル findMedianSortedArrays(ベクトル< INT >&nums1、ベクトル< INT >&nums2){ // 時間のO(N-M + + 1)/ 2スペースO(N-)溶液、得られた二NUM1のサイズ()、それぞれ、2×2つのアレイへのポインタ、小さな後方への変位の各々と INT N1 = nums1.size(); int型 N2 = nums2.size(); int型ID1、ID2; int型(MID = + N2 + N1は、1。)/ 2 ; int型 I = 0、J = 0 ; int型 CUR = INT_MIN; 一方(MID =!0 && IがN1 && Jが<<N2){ ミッド - 。 もし(nums1 [I] < nums2 [J]) ID1 = nums1 [I ++ ]。 他 ID1 = nums2 [J ++ ]; } 一方(MID =!0 && iは< N1){ ミッド - 。 ID1 = nums1 [I ++ ]; } 一方(MID =!0 && J < N2){ ミッド - 。 ID1 = nums2 [J ++ ]; } もし、((N1 + N2)%2== 1)戻りID1。 ID2 =分((J> = N2 INT_MAX:nums2 [J])、(I> = N1?INT_MAX:nums1 [I]))。 返す ダブル(ID1 + ID2)* 0.5 ; } }。