6

subarray の最小スライスに関するコードの質問に対する解決策を見つけようとしています。Kadaneのアルゴリズムの修正版を使用して解決策を考案しました。私は現在、90/100 を取得しており、O(n) のほぼすべてのテストに合格することができました。ただし、「medium_range、増加、減少 (レグス = ~100)、および小さな機能、期待される 5 の 3」を渡すことができないようで、その理由がわかりません。これはおそらく解決策の繰り返しですが、私は少し異なる解決方法を使用しています。

私の論理は次のとおりです。

a) 配列 MinA がある場合、MinA[k] は k から始まり、最小長が 2 の部分配列の最小平均スライスを表します。

b) 次に、MinA をループして配列の最小値を見つけると、これが配列全体の最小平均スライスになります (そして、インデックス位置を返します)

c) この MinA を作成するには、配列の最後から 2 番目の要素から開始し、MinA[A.length -2] は A の最後の 2 つの要素の平均です。

d) カウンターを 1 ポジション左に移動します。MinA[カウンター] は、A[カウンター] と A[カウンター + 1] の平均、または要素カウンターと MinA[カウンター + 1] 内の要素の平均のいずれかでなければなりません。

e) d が真でない場合、これは、MinA[カウンター + 1] が、カウンター + 1 からカウンター + 2 から N までの何らかの要素までの最小平均スライスではないことを意味します。

私は何かが足りないのだろうか?

/*
 * Using modified version of Kadane's algorithm
 * The key logic is that for an array A of length N, 
 * if M[k + 1] is the minimum slice of a subarray from k + 1 to any element
 * between k+2 to n, then M[k] is either the average of A[k] and A[k + 1], or
 * the average of the elements k and the elements in M[k + 1]
 */
function solution(A) {
    // you can use console.log for debugging purposes, i.e.
    // console.log('this is debug message');
    // write your code in JavaScript (ECMA-262, 5th edition)
    var minSliceArray = [],
        counter = A.length - 2,
        currMinSliceLength = 0,
        min = Number.POSITIVE_INFINITY,
        minIndex = -1;

    minSliceArray[counter] = (A[counter] + A[counter + 1]) / 2;
    currMinSliceLength = 2;
    counter--;

    while (counter >= 0) {
        var a = (A[counter] + A[counter + 1]) / 2,
            b = (A[counter] + minSliceArray[counter + 1] * currMinSliceLength) / (currMinSliceLength + 1) ;
        if (a < b) {
            minSliceArray[counter] = a;
            currMinSliceLength = 2;
        } else {
            minSliceArray[counter] = b;
            currMinSliceLength++;
        }
        counter--;
    }

    //loops through the minSliceArray and find the minimum slice
    for (var i = 0; i < minSliceArray.length; i++) {
        if (minSliceArray[i] < min) {
            min = minSliceArray[i];
            minIndex = i;
        }
    }
    return minIndex;
}
4

5 に答える 5

5

問題を解決するには、コードを置き換えることができます

if (a < b) {

if (a <= b) {

たとえば、A = [-3, 3, -3, 3, -3] の場合、最初に A[3:5] を検討します。平均は 0 です。次に、位置 2 の A[2: 5]/3 = -1、および A[2:4]/2 = 0. したがって、前者を選択します。位置 1 の場合、A[1:3]/2 == A[1:5]/4 == 0です。古い回答では、A[1:5] を引き続き選択する必要があります。最後に、位置 0 については、A[0:2]/2 = 0、および A[0:5]/5 = -0.6 となり、後者を選択します。結局、全体の最小平均は、A[3:5]/3=-1 として 3 番目の位置にあります。しかし、実際には A[0:3]/3 == -1 == A[3:5]/3 です。

このような罠があるため、ブログでは Kadane のアルゴリズムの修正版を使用しませんでした。しかし、それはうまくいくはずです。

于 2014-03-04T22:29:48.710 に答える
0

Sheng の修正は役に立ちますが、このアルゴリズムはまだすべての場合に機能するとは限りません。たとえば、アルゴリズムは を返し2ます[-18, 65, -11, 73, -22, 90, 21, 10, 47, 87]。期待値は0です。

考えられる原因:

アルゴリズムの中間ステップを考えてみましょう。A[i..j] が i で始まるスライスの最小平均値を持つ場合、i-1 の要素を含めるには、次のオプションのみが考慮されます。

  • A[i-1...j]
  • A[i-1...i]

k残念ながら、 のようなインデックスが存在する可能性がありますavg(A[i...k]) > avg(A[i...j])が、avg(A[i-1...k]) < avg(A[i-1...j]). これは数学的に証明できますが、ここでは 1 つの例で十分です。

[-18, 65, -11, 73, -22, 90, 21, 10, 47, 87] avg([65, -11, 73, -22]) = 26.25 avg([65, -11]) = 27 // This is ignored as avg is higher

-18 を含めるために、アルゴリズムは と を考慮[-18, 65, -11, 73, -22][-18, 65]ます。

avg([-18, 65, -11, 73, -22]) = 17.4 avg([-18, 65]) = 23.5 avg([-18, 65, -11]) = 12 // True minimum which is not considered

同様のソリューションを提出したところ、Codelity で 100% のスコアを獲得しました。ただし、それは正しい解決策ではありません。

于 2016-08-17T08:54:59.813 に答える
0

どうですか

Javascript

function solution(A) {
    var minpos = 0,
        minavg = (A[0] + A[1]) / 2,
        N = A.length,
        N1 = N - 1,
        N2 = N - 2,
        sumTwo,
        t,
        i;

    for (i = 0; i < N2; i += 1) {
        sumTwo = A[i] + A[i + 1];
        t = sumTwo / 2;
        if (minavg > t) {
            minavg = t;
            minpos = i;
        }

        t = (sumTwo + A[i + 2]) / 3;
        if (minavg > t) {
            minavg = t;
            minpos = i;
        }

    }

    t = (A[N2] + A[N1]) / 2;
    if (minavg > t) {
        minavg = t;
        minpos = N2;
    }

    return minpos;
}

var A = [4, 2, 2, 5, 1, 5, 8];

console.log(solution(A));

jsFiddleについて

于 2014-03-03T04:41:49.170 に答える