ジェイソン:
私はあなたが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
最後の要素の値に。また、すでに合計に追加された、左右からのどの要素を覚えておくことは、インデックス変数を必要としています。
もし
sumleft == sumright
、テスト左右からの次の要素は、要件を満たすためにドロップすることができます。その場合は- >行わ。左右からの次の要素を取り、それぞれの和変数に追加していない場合。1へ戻ります。場合は
sumleft < sumright
、左から次の値を追加しますsumleft
。1へ戻ります。- 場合は
sumleft > sumright
、右から次の値を追加しますsumright
。1へ戻ります。
すべての要素が消費された場合は、解決策はありません。