アルゴリズムの問題は - 2つの注文の配列の中央値を探してください

タイトル説明

サイズとnums1 mとnはn​​ums2二順序付けられた配列を与え。

メジアンおよび整然とした配列の両方を検索し、アルゴリズムの時間複雑さを必要としてくださいは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

おすすめ

転載: www.cnblogs.com/hao-yu/p/11647855.html