O(N)に均等に3部にアレイを分割する2つの要素をドロップ

ジェイソン:

私はあなたが3つの部分の合計が等しくなるようにする配列内の2つの要素をドロップできるように問題が発生しました。

  Ex:
  1 2 4 3 5 2 1
  After I drop the 4 and 5, it becomes 1, 2 | 3 | 2, 1

制約:

  1.Numbers are all integer > 0

  2.Drop two elements in the array, so the three splitted subarrays will have same subarray sum.

私は、次のように2つのパス・アルゴリズムを使用して、それを試してみました

最初のパス:私は簡単に範囲の合計を得ることができるので、O(n)が、左からの累積合計をカウントします。

第二のパス:O(N ^ 2)を使用するネストされたループは部分配列の開始と終了インデックスを取得します。その後、左、中央、右の合計を計算します。

// 1.get accumulated sum map
int[] sumMap = new int[A.length];
int sum = 0;
for(int i = 0; i < A.length; i ++) {
    sum += A[i];
    sumMap[i] = sum;
}

// 2.try each combination
for(int i = 1; i < A.length - 1; i ++) {
    for(int j = i + 1; j < A.length - 1; j ++) {
        int left = sumMap[i] - A[i];
        int mid = sumMap[j] - sumMap[i] - A[j];
        int right = sumMap[A.length - 1] - sumMap[j];

        if(left == mid && mid == right)return true;
    }
}

O(n)を達​​成することができます任意のより良いアルゴリズムがありますか?

感謝

マイケルButscher:

最初と最後の要素をドロップすることができないと仮定すると、すべての要素があります>0

変数を設定しsumleft、最初の要素の値にsumright最後の要素の値に。また、すでに合計に追加された、左右からのどの要素を覚えておくことは、インデックス変数を必要としています。

  1. もしsumleft == sumright、テスト左右からの次の要素は、要件を満たすためにドロップすることができます。その場合は- >行わ。左右からの次の要素を取り、それぞれの和変数に追加していない場合。1へ戻ります。

  2. 場合はsumleft < sumright、左から次の値を追加しますsumleft1へ戻ります。

  3. 場合はsumleft > sumright、右から次の値を追加しますsumright1へ戻ります。

すべての要素が消費された場合は、解決策はありません。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=166205&siteId=1