C++での2つの重複しないサブアレイの最大合計
整数の配列Aがあるとします。重複しない2つのサブ配列で要素の最大合計を見つける必要があります。これらのサブアレイの長さはLとMです。
つまり、より正確に言えば、最大のVを見つける必要があります
V =(A [i] + A [i + 1] + ... + A [i + L-1])+(A [j] + A [j + 1] + ... + A [j + M-1])およびいずれかの-
-
0 <=i
-
0 <=j
これを解決するには、次の手順に従います-
-
n:=Aのサイズ
-
サイズnの配列leftLを定義し、サイズnの配列leftMを定義します
-
サイズnの配列rightLを定義し、サイズnの配列rightMを定義します
-
ret:=0、temp:=0
-
iを初期化する場合:=0、i
-
temp =temp + A [i]
-
-
i:=L、j:=0を初期化する場合、i
-
leftL [i − 1]:=温度とxの最大値。ここで、i − 2 <0の場合はxは0、それ以外の場合はx =leftL [i − 2]
-
temp =temp + A [i]
-
temp =temp − A [j]
-
-
leftL [n − 1]:=温度の最大値、およびx(n − 2 <0の場合はxは0、それ以外の場合はx:=leftL [n − 2]
-
temp:=0
-
iを初期化する場合:=0、i
-
temp =temp + A [i]
-
-
i:=M、j:=0を初期化する場合、i
-
temp =temp + A [i]
-
temp =temp-A [j]
-
-
leftM [n − 1]:=温度の最大値とxの場合はx:=0(n-2 <0の場合)それ以外の場合はx:=leftM [n − 2]
-
temp:=0
-
i:=n − 1を初期化する場合、i> n − 1 − Lの場合、iを1つ減らしますdo −
-
temp =temp + A [i]
-
-
iを初期化する場合:=n − 1 − L、j:=n − 1、i> =0の場合、iを1減らし、jを1減らし、do −
-
rightL [i + 1]:=温度とxの最大値。ここで、i + 2> =nの場合はxは0、それ以外の場合はx =rightL [i + 2]
-
temp =temp + A [i]
-
temp =temp − A [j]
-
-
rightL [0]:=tempとrightL[1]
の最大値 -
temp:=0
-
i:=n − 1を初期化する場合、i> n − 1 − Mの場合、iを1つ減らしますdo −
-
temp =temp + A [i]
-
-
iを初期化する場合:=n − 1 − M、j:=n − 1、i> =0の場合、iを1減らし、jを1減らし、do −
-
rightM [i + 1]:=温度とxの最大値。ここで、i + 2> =nの場合はxは0、それ以外の場合はx:=rightM [i + 2]
-
temp =temp + A [i]
-
temp =temp − A [j]
-
-
rightM [0]:=tempとrightM[1]
の最大値 -
iを初期化する場合:=L − 1、i <=n − 1 − Mの場合、iを1つ増やしますdo −
-
ret:=retとleftL[i] + rightM [i + 1]
の最大値
-
-
iを初期化する場合:=M − 1、i <=n − 1 − Lの場合、iを1つ増やしますdo −
-
ret:=retとleftM[i] + rightL [i + 1]
の最大値
-
-
retを返す
理解を深めるために、次の実装を見てみましょう-
例
#include <bits/stdc++.h> using namespace std; class Solution { public: int maxSumTwoNoOverlap(vector<int>& A, int L, int M) { int n = A.size(); vector <int> leftL(n); vector <int> leftM(n); vector <int> rightL(n); vector <int> rightM(n); int ret = 0; int temp = 0; for(int i = 0; i < L; i++){ temp += A[i]; } for(int i = L, j = 0; i < n; i++, j++){ leftL[i − 1] = max(temp, i − 2 < 0 ? 0 : leftL[i − 2]); temp += A[i]; temp −= A[j]; } leftL[n − 1] = max(temp, n − 2 < 0 ? 0 : leftL[n − 2]); temp = 0; for(int i = 0; i < M; i++){ temp += A[i]; } for(int i = M, j = 0; i < n; i++, j++){ leftM[i − 1] = max(temp, i − 2 < 0 ? 0 : leftM[i − 2]); temp += A[i]; temp −= A[j]; } leftM[n − 1] = max(temp, n − 2 < 0 ? 0 : leftM[n − 2]); //out(leftM); temp = 0; for(int i = n − 1; i > n − 1 − L; i−−){ temp += A[i]; } for(int i = n − 1 − L, j = n − 1; i >= 0 ; i−−, j−− ){ rightL[i + 1] = max(temp, (i + 2 >= n ? 0 : rightL[i + 2])); temp += A[i]; temp −= A[j]; } rightL[0] = max(temp, rightL[1]); temp = 0; for(int i = n − 1; i > n − 1 − M; i−−){ temp += A[i]; } for(int i = n − 1 − M, j = n − 1; i >= 0 ; i−−, j−− ){ rightM[i + 1] = max(temp, (i + 2 >= n ? 0 : rightM[i + 2])); temp += A[i]; temp −= A[j]; } rightM[0] = max(temp, rightM[1]); for(int i = L − 1; i <= n − 1 − M; i++){ ret = max(ret, leftL[i] + rightM[i + 1]); } for(int i = M − 1; i <= n − 1 − L; i++){ ret = max(ret, leftM[i] + rightL[i + 1]); } return ret; } }; main(){ Solution ob; vector<int> v1 = {0,6,5,2,3,5,1,9,4}; cout << (ob.maxSumTwoNoOverlap(v1, 1, 2)); }
入力
[0,6,5,2,3,5,1,9,4] 1 2
出力
20
-
C++のMを法とする2つの数値の合計
この問題では、a、b、Mの3つの数値が与えられます。私たちのタスクは、Mを法とする2つの数値の合計を求めるプログラムを作成することです。 問題を理解するために例を見てみましょう Input: a = 14 , b = 54, m = 7 Output: 5 Explanation: 14 + 54 = 68, 68 % 7 = 5 この問題を解決するには、aとbの数字を追加するだけです。そして、Mで割ったときの余りを出力します。 例 ソリューションの動作を説明するプログラム #include <iostream> using namespace std; int moduloSu
-
TwoSumIV-入力はC++のBSTです
二分探索木と1つのターゲット値があるとします。合計が指定されたターゲットと等しくなるように、BSTに2つの要素が存在するかどうかを確認する必要があります。 したがって、入力が次のような場合 その場合、出力はTrueになります。 これを解決するには、次の手順に従います- 配列を定義するv 関数inorder()を定義します。これはルートになります ルートがnullの場合、- 戻る 順序なし(ルートの左側) ルートの値をvに挿入 順序なし(ルートの左側) 関数findnode()を定義します。これにはkがかかります n:=vのサ