整数の配列を考えると、最大1つの要素の削除と空でない部分配列(連続する要素)の最大合計を返します。言い換えれば、あなたは、サブアレーを選択して、そこにまだ残って少なくとも一つの要素であり、残りの要素の合計が可能な最大になるように、必要に応じてそれから一つの要素を削除したいです。
部分配列は一つの要素を削除した後、非空であることが必要であることに注意してください。
例1:
入力:ARR = [1、-2,0,3] 出力:4 説明:我々が選択できるので、[1、-2、0、3]及びドロップ-2、従ってサブアレイ[1、0,3]となります最大値。
例2:
入力:ARR = [1、-2、-2,3] 出力:3 説明:私達はちょうど[3]を選択し、それが最大の合計です。
例3:
入力:ARR = [-1、-1、-1、-1] 出力:-1 説明:最終サブアレイが空である必要があります。あなたは[-1]を選択し、削除することはできません-1それから、その合計は0に等しい作るために、空の部分配列を取得します。
制約:
1 <= arr.length <= 10^5
-10^4 <= arr[i] <= 10^4
Kadaneのアルゴリズムの変動は最大サブアレイ合計を取得します。
最終的な答えは、次の2例1でなければなりません。
1.いかなる要素は削除されません。これは、最大サブアレイ合計と同等です。
2.一つの要素が削除されます。[I]が削除されたARR、[I + 1] - [1 i]およびstartAt我々は2個の分離されたサブアレイの最大和、ENDATを見つけるにこれを低減することができます。ENDATは、[I - 1]すでにケース1で計算されたがだから我々はちょうどstartAt [I + 1]を計算するために再びKadaneのアルゴリズムを適用する必要があります。我々は右から左に編曲繰り返す場合startAtはENDATと同じです。
最大の結果を求める際考えるべきいくつかの例。
1.私たちはstartAt最大サブアレイの結果の配列を計算するときの最大を見つける必要がありますか?いいえ、すべてのstartAtはすでにその最大の結果を計算した別のENDATのミラーですので。
2.分離サブアレイのケース2については、我々は唯一の左右両方のサブアレイが空でない場合を考慮する必要があります。左の部分配列が空の場合、それはありません削除してstartAtとなりますので、これは本当です。右の部分配列が空の場合も同様、それはありません削除してENDATになります。これら2例の両方がカバーされています。
クラスソリューション{ 公共 のint maximumSum(INT [] ARR){ int型 N = arr.length、RESの=のARR [0 ]。 INT [] maxEndAt = 新しい INT [N]。 INT [] maxStartAt = 新しい INT [N]。 maxEndAt [ 0] =のARR [0 ]。 以下のために(int型 i = 1; iがn <; iは++ ){ maxEndAt [I] = Math.max(maxEndAt [I - 1] + ARR [i]は、ARR [I])。 RES = Math.max(RES、maxEndAt [I])。 } maxStartAt [N- 1] =のARR [N - 1 ]。 以下のために(int型 I = N - 2; I> = 0; i-- ){ maxStartAt [I] = Math.max(ARR [I] + maxStartAt [I + 1 ]、ARR [I])。 } のために(int型 i = 1; iがN < - 1; iが++ ){ 場合(ARR [I] <0 ){ RES = Math.max(RES、maxEndAt [I - 1] + maxStartAt [I + 1 ])。 } } 戻りRES。 } }
この問題は、分離左と右のDPアレイとの点で自己を除きアレイの製品と同様です。
アレイ所与 nums
の n個の 整数 、nは > 1、配列返す output
ような output[i]
すべての要素の積に等しい nums
以外を nums[i]
。
例:
入力:[1,2,3,4]
出力:[24,12,8,6]
注:(分裂なしとOでそれを解決してくださいN)。
クラスソリューション{ 公共 のint [] productExceptSelf(INT [] NUMS){ 場合(NUMS == NULL || nums.length <= 1 ){ 戻りNUMS。 } int型 [] leftProduct = 新しい INT [nums.length]。 leftProduct [ 0] = NUMS [0 ]。 以下のために(int型 i = 1; iはnums.length <; iは++ ){ leftProduct [I] = leftProduct [I-1] * NUMS [I]。 } int型 [] rightProduct = 新しい INT [nums.length]。 rightProduct [nums.length - 1] = NUMS [nums.length - 1 ]。 以下のために(int型 I = nums.length - 2; I> = 0; i-- ){ rightProduct [I] = rightProduct [I + 1] * NUMS [I]。 } int型 [] productArray = 新しい INT [nums.length]。 productArray [ 0] = rightProduct [1 ]。 productArray [nums.length - 1] = leftProduct [nums.length - 2 ]。 用(int型 ; - ; iが+ +1 iがnums.lengthを<I = 1 ){ productArray [I] = leftProduct [I - 1] * rightProduct [I + 1]; } 戻りproductArray。 } }