説明
円形の整数配列(最後の要素の次の要素が最初の要素である)が与えられると、数値の和が最大であるその中の連続部分配列を見つけます。あなたのコードでは、最初の数字のインデックスと最後の数字のインデックスを返す必要があります。
重複した答えが存在する場合、それらのいずれかを返します。
例
例1:
Input: [3, 1, -100, -3, 4]
Output: [4, 1]
例2:
Input: [1,-1]
Output: [0, 0]
チャレンジ
O(N)時間
アイデア:
2例について説明します。
- 最大配列の周期の中央に残っています
- アレイの後に残された最大の中間の一部を除去することです
(最大サブアレイの伝統的な慣行で再び行くために第1のケースを参照して問題を解決します)。少しを証明することができます第二のアプローチは、それが削除さ最小サブアレイ全体の配列になることです、その期間の真ん中を考えます。
だから、再び最小サブアレーを求めた後、二つの状況を比較し、あなたが最適なソリューションを取ることができます
特別な配慮を最小サブアレイがケースにすべての数字を取ることである必要があります。
パブリッククラスソリューション{ / * * @param A:整数配列 * @return:整数のリストは、最初の数の指標と最後の番号のインデックス含む * / クラス結果{ 公共のint maxSumと、 公共int型leftIdx、rightIdx。 } // COEF = 1:最大非空サブアレイ見つける // COEF = -1:最大空でない部分配列を見つける // A [I] * = COEFの 結果findMax(INT [] A、int型COEFを){ / / Sjと// S {I-1} // I-1 のint J、nowSum = 0、prevMinSum = 0、prevMinIdx = -1。 RES =新しい検索結果を()結果; res.maxSum =はInteger.MIN_VALUE。 {(; J <A.length ++ J、J = 0)ため nowSum + = A [j] * COEF。 // Sj- prevMinSum 場合(nowSum - prevMinSum> res.maxSum){ res.maxSum = nowSum - prevMinSum。 res.leftIdx = prevMinIdx。// I - 1 res.rightIdx = J; } {(nowSum <prevMinSum)場合 prevMinSum = nowSum。 prevMinIdx = J; } } RESを返します。 } パブリックリスト<整数> continuousSubarraySumII(INT [] A){ maxの結果= findMax(A、1); 結果分= findMax(A、-1)。 min.maxSum * = -1; int型totSum = 0; 以下のために(INT I 0 =; I <A.length; ++ I){ totSum + = A [i]は、 } リスト<整数> RES =新規のArrayList <>(); IF(max.maxSum> = totSum - min.maxSum){ res.add(max.leftIdx + 1)。 res.add(max.rightIdx)。 } 他{ //特別な場合 であれば(min.leftIdx == -1 && min.rightIdx == A.length - 1){ res.add(max.leftIdx + 1)。 res.add(max.rightIdx)。 } 他{ // min.rightIdx + 1 ...でlen-1、0、1、... min.leftIdx //は、分間隔の相補的な間隔を使用します // [min.leftIdx + 1 ... min.rightIdx] res.add(min.rightIdx + 1)。 res.add(min.leftIdx)。 } } RESを返します。 } }