2つの注文の配列の中央値を探して
サイズとnums1 mとnはnums2二順序付けられた配列を与え。
メジアンおよび整然とした配列の両方を検索し、アルゴリズムの時間複雑さを必要としてくださいはO(ログ(M + N))です。
あなたはnums1とnums2両方が空を負いかねます。
例1:
nums1 = [1,3]
nums2 = [2]
中央値は2.0である
実施例2:
nums1 = [1、2]
nums2 = [3、4]
中央値は、(2 + 3)/ 2 = 2.5であります
この問題を解決するために、我々は理解する必要があり、「中央値の役割とは何か。」統計では、中央値がに使用されます。
一つは、要素のサブセットはサブセット中の他の要素よりも常に大きい、請求等しい長さの2つのサブセット、にセット。
奇数と偶数のグループに分割されます。
奇数:[235] 3の中央値に対応
偶数番目のグループ:[1479](4 + 7)/ 2 = 5.5の中央値に対応
最初の「カット」を説明
左された2つの要素を有することになる(カット)切断について、我々は2つの部分に分けることができる順序付けられたアレイにカットバック左右、カット(切断)と呼ばれていたナイフを切断右側の最大値と最小値。
私たちは、RMIN = MIN(RightPart)、LMAX =マックス(LeftPart)を定義します。
二つの数が途中で切断することができるカット、数に切断した場合、この数は、すなわち左に属し、1の数で切断することができる、また、右に属し
奇数:[235] 3の中央値に相当するが、3で切断(カット)を仮定して、我々は、2つの3に分けることができる:[2(3/3)5]
したがってLMAX = 3、RMIN = 3
偶数番目のグループ:[1479] 4と7の間の切断(カット)を仮定すると、(4 + 7)/ 2 = 5.5の中央値に対応する:[1(4/7)9]
したがってLMAX = 4、RMIN = 7
そして、のk番目の要素の切断
配列を
位置kビット(真ん中の2つの数字に(カット)を切断しない)、次いで、LMAX = RMIN = A [K]における切断(カット)場合、アレイAのために、順序付けられたアレイに 、
二つの配列
二つの配列が規則配列に結合されたときに私達の状態の対象である、我々は、kビットの最初の要素を要件を有します
私たちは、設定:
Ciはi番目の配列をカットすることです。
LMaxi i番目の配列要素のカットの後に左。
RMini右切断のi番目の配列要素。
まず、LMax1 <= RMin1、LMax2 <= RMin2ほぼ等しく、その後、数に配列が左から右に比べて確かに少なく、注文されているので!しかし、カット(カット)場合は、確かだという。
第二に、我々はLMax1を許可すれば、<= RMin2、LMax2 <= RMin1それ
そう左の要素の数がちょうど和kに等しい場合、全体が、左半分の右半分より小さい場合、k番目の要素はMAX(LMax1、LMax2)はMaxは(LMax1、LMax2)確か左ので、これはより良く理解されます合わせたアレイは、最大のものの前に確実にk個の要素のk番目の要素を順序付けられているため、最大値の要素をKです。
LMax1> RMin2は、アレイ1の左側の要素は(マルチ)が大きすぎる説明あれば、我々は、C1、C2 = K-C1が対応して増加されて減少しました。LMax2> RMin1同様に、C2を低減する、C1 = K-C2は、対応して増加されます。
仮定すると、K = 3
以下のために
[2 3 5]
【1479】
設定C1 = 1、C2 =次いでK - C1 = 2
[2月3日5]
[1 4月7日9]
この場合LMax1 = 2、RMin1 = 3、LMax2 = 4、RMin2 = 7、
したがってLMax2> RMin1は、以前の推論の下で、我々は、C1が増加したいので、次のように我々は、C1 = 2ましょう:
[2 6/10]
[1/4〜7 9]
この場合LMax1 = 3、RMin1 = 5、LMax2 = 1、RMin2 = 4、第三の要素は、MAX(LMax1、LMax2)= 3となるようにLMax1 <RMin2とLMax2 <RMin1を満たします
最大の問題は、それも可能である2つのアレイは、その合併、m + nは総数後奇数であってもよいことであるので、我々はメートルの考えを確認する必要があります+ nは常に偶数であります
仮想 '#' を添加することによって、我々は、M + 1に変換してみましょうnは2mが2N + 1に変換され、2つの数字が2メートル+ 2N + 2、定数にもなります。
仮想プラスは、実際には、このステップは、以下の変換、我々はオリジナルの要素を持つ仮想プラス1の対応の各要素を確保することができなかったことに注意してください
このような仮想加えた後、各位置は、要素/ 2の元の位置によって得ることができます。
例えば、図2に示すように、元のビット0に、ビット1は今= 0 1/2であります
例えば図3は、オリジナルでは、今3、3/2 = 1であります
5例で、2つの元、今5、= 2 5/2
例えば図9に示すように、元の3には、今7、7/2 = 3であります
切断(カット)するために、「#」でカット数にカット2つの切断要素間等しい場合数指定部2に等しく、常に次ホールドがあります。
LMaxi =(CI-1)要素に/第二の位置
/ 2位置にRMini = CI要素
例えば:
C = 3,3に切断、LMAXは、[(3-1)/ 2] [1]、RMINは、[3/2] = A [1]、位置がわずか3 ===します!
4/7 '#' との間に切断、C = 4、LMAX = A [(4-1)/ 2] [1] = 4、RMIN = A [4/2] = A [2] = 7 =
物事の残りの部分が容易になります、Aの仮想配列として見二つの配列は、Aは2メートル+ 2N + 2つの要素、+ 1メートルでカット+ Nを持っているので、我々はちょうどメートルを見つける必要がある+ + 1のn元素とM + N +ライン上の第二の位置の要素位置。
左:[M + N + 1] = MAX(LMax1、LMax2)
右:[M + N + 2] = MIN(RMin1、RMin2)
==>ミッド=([M + N + 1] + A [M + N + 2])/ 2 =(MAX(LMax1、LMax2)+ MIN(RMin1、RMin2))/ 2
最速のカット(カット)は、二分法の使用であります
我々はそれの半分を行う2つの配列が、ありますか?
以前の分析によると、私たちは、知っている限り、C1またはC2が決定されるように、他にも決定します。ここでは、効率のために、我々は確かに行うには、C1を想定している短い半分の長さを選択しています。
C1、C2増加を低減LMax1> RMin2、。 - > C1左半分
LMax2> RMin1は、C1、C2の減少を増加させます。 - > C1-半分の権利
C1またはC2は、単純に行う方法を実行していた場合は?
これが発生します。中央値よりも小さいか大きいの完全な配列がある場合。そのN <Mをとる4つの場合があります。
C1 = 0 - 全体として1が正しい配列であるので、値はアレイ2内の中央値よりも大きい場合、単にアレイ1カットの左側が空であることを意味するので、我々は仮定することができるLMax1 = INT_MINその
C1 = 2N - 1アレイ全体、左の値はアレイ2における中央値未満であるので、単にアレイ1カットの右側が空であることを意味するので、我々はそのRMin1 = INT_MAXをとることができる、とされていますLMax2 <RMin1恒久的施設を確保
右側C2は= 0--全体アレイ2、値はアレイ1の中央値よりも大きいので、単にアレイ2カットの左側が空であることを意味するので、我々はそのLMax2 = INT_MIN仮定することができます
左側のC2は= 2m--全体アレイ2、そう値はアレイ1における中央値未満では、単にアレイ2カットの右側は、我々はできるLMax1 <RMin2永久確立を可能にするために、空であることを意味しますRMin2 = INT_MAを想定
答えの対象
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 4 クラスソリューション{ 5 公共: 6 ダブル findMedianSortedArrays(ベクトル< INT >&nums1、ベクトル< INT >&nums2){ 7 INT N = nums1.size()。 8 INT M = nums2.size()。 9 もし(N> M){ 10 リターンfindMedianSortedArrays(nums2、nums1)。 11 } 12 INT LMax1、LMax2、RMin1、RMin2、C1、C2、LO =0、ハイ= 2 * N-; 13である 一方(LO <= こんにちは){ 14 C1 =(LO +ハイ)/ 2 ; // C1二分結果 15 C2 = M + N - C1; 16 LMax1 =(C1 = = 0)INT_MIN :? nums1 [(C1 - 1)/ 2 ]; 17。 Rmin1 =(C1の== 2 * N-)INT_MAX:nums1 [C1 /?2 ]; 18である Lmax2 =(C2 == 0)INT_MIN :? nums2 [(C2 - 1)/ 2 ]; 19。 RMin2 =(C2 == 2 * Mの)?INT_MAX:nums2 [C2 / 2 ]。 20 coutの<< LMax1 << " " << RMin1 << てendl; 21 coutの<< LMax2 << " " << RMin2 << てendl; 22 であれば(LMax1> RMin2) 23 HI = C1 - 1 。 24 他の 場合(LMax2> RMin1) 25 LO = C1 + 1 26。 他の 27 休憩。 リターン(MAX(LMax1、LMax2)+分(RMin1、RMin2))/ 2.0 。 30 } 31 }。 32 33 INT メイン(){ 34 ベクター< INT > A = { 1、2、3 }。 35 ベクター< INT > B = { 4、5、6、7 }。 36 ソリューションSU。 37 COUT << su.findMedianSortedArrays(B)<< ENDL。 38 リターン 0 ; 39 }