タイトル説明
サイズと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であります
出典:滞在ボタン(LeetCode)
リンク:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
問題の解決策
私の解決策:
私の考え:2つの配列のソートの合併後、次に中央値を見つけます。
private static double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length==0&&nums2.length==0){
return 0;
}
double media = 0;
int[] both = new int[nums1.length+nums2.length];
System.arraycopy(nums1,0,both,0,nums1.length);
System.arraycopy(nums2,0,both,nums1.length,nums2.length);
Arrays.sort(both);
if (both.length%2==0){
media=(both[both.length/2-1]+both[both.length/2])/2.0;
} else {
media=both[both.length/2];
}
return media;
}
本明細書で使用する場合、APIのJavaはマージとアレイ、ビットトリッキーソートの簡略化された動作を提供するが、実際に被験者の要件を満たしていない、被験体は、時間の複雑さを必要とする他の人が見えるように、((M + N)ログ)Oでありますそれを行う方法
公式ソリューション:
アイデア:
この問題を解決するために、我々は理解する必要があり、「中央値の役割とは何か。」統計では、中央値がに使用されます。
一つは、要素のサブセットはサブセット中の他の要素よりも常に大きい、請求等しい長さの2つのサブセット、にセット。
あなたは中央の部門の役割を理解していれば、私たちはその答えに非常に近いだろう。
まず、A iの任意の位置で、私たちは2つの部分に分かれてみましょう:
left_A | right_A
A[0], A[1], ..., A[i-1] | A[i], A[i+1], ..., A[m-1]
そこm個の要素Aであるので、我々は、M + 1つの分割方法(i = 0〜m)を有するからです。
我々はそれを知っています:
LEN(left_A)= I、LEN(right_A)= M-I。
注:I = 0、left_A空集合、及びI = M、right_A空集合。
同様に、我々は、Bは2つの部分に分かれている任意の位置jで次のようになります。
left_B | right_B
B[0], B[1], ..., B[j-1] | B[j], B[j+1], ..., B[n-1]
left_A left_Bやコレクションに、別のセットright_Aとright_Bに入れました。そして、これら二つの新しいコレクションの名前left_partとright_part:
left_part | right_part
A[0], A[1], ..., A[i-1] | A[i], A[i+1], ..., A[m-1]
B[0], B[1], ..., B[j-1] | B[j], B[j+1], ..., B[n-1]
私たちが確認できた場合:
LEN(left_part)= LEN(right_part)
最大(left_part)≤min(right_part)
そこで、{A、B}は、等しい長さの2つの部分に分割されているすべての要素を有し、ここで、素子部は、要素の他の部分よりも常に大きいです。その後:
中央値= [MAX(left_part)+分(right_part)] / 2
この二つの条件を確保するために、我々は唯一のことを確認する必要があります。
私は[I-1]と仮定し、分析を単純化するためにps.1は、B [j-1]、A [i]は、B [j]は、それがI = 0、I = M、表示された場合であっても、常に存在している 、J = 0をまたはJ = Nなどの重要な条件。
私は最後に、これらの重要な値に対処する方法を説明します。
なぜps.2n≥m?0≤i≤m及びj =(M + N + 1)/ 2-iのため、I jが負ではないようにする必要があります。N <M場合は、jが負になり、これは間違った答えの原因となります。
そこで、我々は、実行する必要があります。
私はその中に[0、M]でターゲットオブジェクトを検索し、見つけます。
B[j−1]≤A[i] 且 A[i−1]≤B[j], 其中 j=(m+n+1)/2−i
その後、我々は、バイナリツリーの検索をすることができ、次の手順を実行します。
1.設定IMIN = 0、IMAX = mが、その後で、[のIMAX、IMIN]検索を開始します。
2.令 i=(imin+imax)/2 , j=(m+n+1)/2−i
3.今、私たちがlenている(left_part)= LEN(right_part)。そして、我々は唯一の三つの条件を満たしています:
B [J-1]≤A[ I] とA [I-1]≤B[ J]:
これは、我々は、対象物iを見つけることを意味し、あなたが探して停止することができます。
B [J-1]> A [i]は:
これは、A [i]が小さすぎることを意味し、私たちは私にB [J-1]≤A[調整する必要が I]を。
私たちは、私が増加することができますか?
時間が私を大きくすると、jが削減されるためです。
こうしてB [J-1]を低減することができる、とA [i]が増加し、B [j-1]≤Aは[ i]を満足させることができます。
私たちは、私が行う減らすことができますか?
いいえ、私は減少したときので、jが増加されます。
こうしてB [J-1]が増加し、A [i]が減少され、その後、B [j-1]≤Aは、[ i]は満たしていてもよいです。
だから私たちは私を増やす必要があります。言い換えれば、我々はあなたの検索[I + 1、IMAX]を調整する必要があります。
したがって、IMINを設定=私は1を+、および2に進みます。
[I-1]> B [j]は:
これは私たちが私A [I-1]≤B[減らす必要があるように、[I-1]は、あまりにも大きいことを意味 j]を。
言い換えれば、私たちはあなたの検索を調整する必要がある[回数i minを、I-1]。
したがって、IMAXの設定= I-1、及び2に進みます。
M + Nが奇数である場合MAX(A [I-1]、B [J-1]):私は、中央値をターゲットオブジェクトを見つける場合
[MAX([-I 1]、B [-J 1])+分([I]、B [J])] / 2 、M + Nが偶数である場合
今、我々は閾値I = 0、I = mを、考える 、J = 0、J = Nをこのとき、A [I-1]、B [J-1]、A [i]は、B [j] それは存在しないかもしれません。
実際には、このような場合は、あなたが考えるよりはるかに簡単です。
私たちは必ずMAX(left_part)≤min(right_part)を作るです行う必要があります 。だから、i、jは(Aは、[I-1]、Bということを意味する臨界値でない場合は 、[J-1]、A [i]は、B [j]は、その後、我々はまた、B [J-1を確認する必要があり、すべての存在します) ]≤A[i]とA [I-1]≤B[ J]が成り立ちます。
しかし、もし] A [I-1]、 B [J-1]、A [i]は、B [j]はセクション内に存在しない、我々は、これらの二つの条件(またはチェックなし)のいずれか一方のみをチェックする必要があります。
I = 0の場合、[I-1]は存在しません。たとえば、そして、我々はA [I-1]≤B[チェックする必要はありません j]が成り立ちます。
そこで、我々は、実行する必要があります。
私はその中に[0、M]でターゲットオブジェクトを検索し、見つけます。
(J = 0又はI = MまたはB [J-1]≤A[I])或是
I = 0又はJ = NまたはA [I-1]≤B[J])、其中のJ =(M + N + 1)/ 2-iの
サイクル検索では、我々は唯一の三つの条件を満たしています:
J = 0又はI = Mまたは B [J-1]≤A[I]) またはI = 0又はJ = Nまたは A [I-1]≤B[J])、 iが完全であることを意味我々は、検索を停止することができます。
J> 0、iは<は、Mおよび B [J-1]> A [i]はiが小さすぎる手段、我々はそれを増加しなければなりません。
I> 0とj <nおよび A [I-1]> B [j]は、この手段IIも、それは低減されなければなりません。
I <m⟹j> 0とI>0⟹j<N常に真、理由は次のとおりです。
そのため、2と3の場合には、我々はJ> 0またはjについてチェックする必要があります<N保持しています。
public double findMedianSortedArrays(int[] A, int[] B) {
int m = A.length;
int n = B.length;
if (m > n) { // to ensure m<=n
int[] temp = A; A = B; B = temp;
int tmp = m; m = n; n = tmp;
}
int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = halfLen - i;
if (i < iMax && B[j-1] > A[i]){
iMin = i + 1; // i is too small
}
else if (i > iMin && A[i-1] > B[j]) {
iMax = i - 1; // i is too big
}
else { // i is perfect
int maxLeft = 0;
if (i == 0) { maxLeft = B[j-1]; }
else if (j == 0) { maxLeft = A[i-1]; }
else { maxLeft = Math.max(A[i-1], B[j-1]); }
if ( (m + n) % 2 == 1 ) { return maxLeft; }
int minRight = 0;
if (i == m) { minRight = B[j]; }
else if (j == n) { minRight = A[i]; }
else { minRight = Math.min(B[j], A[i]); }
return (maxLeft + minRight) / 2.0;
}
}
return 0.0;
}
より多くの困難を理解するために、その問題の解決策は、:?訪問Https://leetcode-cn.com/problems/median-of-two-sorted-arrays