私はhackerrankからこの配列操作の問題をやっていると、それはコンパイルエラーがされて私に指示タイムアウトのために終了します。
小さな配列に完全に私の方法の仕事。このエラーは、より大きな配列値のために起こります。
ここで質問リンクがあります。ここで質問
各動作のために、ゼロの1インデックス付き配列と操作のリストから始まる含め、二つの与えられたインデックス間の配列要素のそれぞれに値を追加します。すべての操作が実行されたら、あなたの配列内の最大値を返します。
例えば、ゼロのあなたの配列の長さ。次のようにクエリのリストは以下のとおりです。
a b k 1 5 3 4 8 7 6 9 1
指標とまでの間の値を追加します。
index -> 1 2 3 4 5 6 7 8 9 10 [0,0,0, 0, 0,0,0,0,0, 0] [3,3,3, 3, 3,0,0,0,0, 0] [3,3,3,10,10,7,7,7,0, 0] [3,3,3,10,10,8,8,8,1, 0]
最大値は、すべての操作が行われた後です。
下記の私の方法です。
static long arrayManipulation(int n, int[][] queries) {
long max = 0L;
long[] arr = new long[n];
for (int i = 0; i < n; i++) {
arr[i] = 0L;
}
for (int i = 0; i < queries.length; i++) {
int[] q = queries[i];
int start = q[0] - 1;
int end = q[1] - 1;
int val = q[2];
long tempMax = updateVal(start, end, val, arr);
if (tempMax > max) {
max = tempMax;
}
}
return max;
}
static long updateVal(int start, int end, int val, long[] arr) {
long max = 0L;
for (int i = start; i <= end; i++) {
arr[i] = arr[i] + val;
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
下記の私のコードでは動作しませんいくつかのテストクラスです。
Test1を Test2を Test3は
これを理解するために私を助けてください。私は、javaに基づいて回答の多くを探索しました。
しかし、私はそれを理解できませんでした。
これが私の最後の手段であります。助けてください。
Kanahaiyaの答えの後に更新しました
static long arrayManipulation(int n, int[][] queries) {
long max = 0L;
int a, b, k;
int[] arr = new int[n + 2];
for (int i = 0; i < queries.length; i++) {
a = queries[i][0];
b = queries[i][1];
k = queries[i][2];
for (int j = 0; j < arr.length; j++) {
if (j >= a) {
arr[j] = arr[j] + k;
}
if (j > b) {
arr[j] = arr[j] - k;
}
}
}
Arrays.sort(arr);
max = arr[arr.length - 1];
return max;
}
まず第一に、あなたはそれを理解していない場合には、Terminated due to timeout
それはあなたの実装が遅すぎることを意味し、コンパイルエラーではありません。課題は、問題への正しい解決策を実装することではありません。ソリューションは、効率的でなければなりません。あなたのソリューションは、非効率的であるので、それは遅すぎることに起因する大規模な入力のために失敗しました。
クエリの数は、配列(あなたが投稿3のテストケースで100K対の10M)の長さよりも小さい2桁のようですので、それだけで、クエリでの作業に、より効率的ではなく、実際には配列を更新します。
私はあなたの実装を提供するつもりはないが、私はあなたの現在の実装よりも効率的であるべきなアルゴリズムを提案します。
私は次のようにクエリを処理勧め:
互いに素サブアレイ範囲とクエリが含まれています処理されたクエリのリストに最初のクエリを追加します。このリストは、(あなたはそれが適切な位置に新しい要素を追加することによってソートし続けます)最初の配列インデックスでソートされます。
(あなたがperformenceを改善するために、バイナリ検索を使用してそれを行うことができます)各クエリは、まだ処理されていないため、それをオーバーラップし、すべての処理されたクエリを見つけます。
結果のクエリはそれぞれ、完全に既存の処理されたクエリに含まれているか、既存の各処理されたクエリに含まれないことになるような方法で現在のクエリを分割します。
スプリットで作成したクエリのそれぞれについて:
- その範囲は、既存の処理クエリの範囲に等しい場合、処理されたクエリにクエリの値を追加します。
- その範囲は、既存の処理済みのクエリに含まれていない場合は、新たに処理されたクエリとしてそのクエリを追加します。
- その範囲は、部分的に既存の処理されたクエリに含まれている場合は、処理されたクエリを分割します。
私は私の説明が明確で十分であるかはわかりません。私は例を紹介します
1 5 3
4 8 7
6 9 1
入力:
処理されたクエリのリストに1 5 3を追加します。
工程4 8 7:1つのずつ処理クエリは重複もあり - 1 5 3。
4 5 7と6 8 7:二つのサブクエリに分割4 8 7。
4 5 7はそう1 3 3及び3 4 5 + 7に1 5 3を分割し、1 5 3に含まれています
6 8 7にあるようにそれを追加し、任意の処理クエリに含まれていません。
今処理したクエリは、次のとおりです。
1 3 3
4 5 10
6 8 7
工程6 9 1:6 8 7:それに重なる1つのずつ処理クエリがあります。
6 8 1,9 9 1:二つのサブクエリに分割6 9 1。
6 8 1 6 8 7 + 1となるであろう同じ範囲6 8 7を有しています
9 9 1は、であるようにそれを追加し、任意の処理クエリに含まれていません。
今処理したクエリは、次のとおりです。
1 3 3
4 5 10
6 8 8
9 9 1
あなたがクエリを処理するとして、あなたはあなたが最大値が10であることを知っているすべてのクエリーを処理するようにした後、最大処理されたクエリの値を追跡します。