C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で合計が指定値以上となる最短の連続部分配列を求める方法

問題概要

n個の要素からなる配列と正整数 s が与えられます。このとき、要素の合計が s 以上となる「連続する部分配列(サブアレイ)」の中で最も短いものの長さを求めてください。条件を満たす部分配列が存在しない場合は、0 を返します。

例えば、配列が [2,3,1,2,4,3]、目標値が 7 の場合、答えは 2 になります。これは部分配列 [4,3] の合計が 7 であり、条件を満たす中で最も短いためです。

解法のアプローチ:スライディングウィンドウ

この問題は「スライディングウィンドウ(双方向ポインタ)」と呼ばれる手法で効率的に解けます。ウィンドウの右端を順に広げながら、合計が条件を満たし続ける限り左端を縮めていくことで、各要素は高々2回しか走査されません。

具体的な手順は以下の通りです。

  • ans := 0、n := 配列Aのサイズ、j := 0、sum := 0 と初期化する

  • i を 0 から n − 1 まで繰り返す

    • sum := sum + A[i]

    • sum − A[j] >= K かつ j <= i の間、次を繰り返す

      • sum := sum − A[j]

      • j を 1 増やす

    • sum >= K である場合

      • ans == 0 または ans > (i − j + 1) ならば、ans := (i − j + 1)

  • ans を返す

C++での実装例

理解を深めるために、以下の実装を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
class Solution {
    public:
    int minSubArrayLen(int K, vector<int>& A) {
        int ans = 0;
        int n = A.size();
        int j = 0;
        int sum = 0;
        for(int i = 0; i < n; i++){
            sum += A[i];
            while(sum - A[j] >= K && j <= i){
                sum -= A[j];
                j++;
            }
            if(sum >= K){
                if(ans == 0 || ans > (i - j + 1)) ans = (i - j + 1);
            }
        }
    return ans;
    }
};
main(){
    vector<int> v = {2,3,1,2,4,3};
    Solution ob;
    cout << ((ob.minSubArrayLen(7,v)));
}

入力

7
[2,3,1,2,4,3]

出力

2

計算量の評価

時間計算量は O(n)、空間計算量は O(1) です。ポインタ i と j はそれぞれ配列を一度しか進まないため、全体的に線形時間で処理が完了します。ブルートフォース(全探索)では O(n²) かかるところを、この手法により大幅に高速化できます。

  1. C++でmを法とする最大部分配列の総和を求めるアルゴリズム

    C++でmを法とする最大部分配列の総和とは この問題では、サイズnの整数型配列と整数mが与えられます。求めるのは、すべての部分配列の総和の中から、mで割った余りが最大となる値です。 問題の概要 − 各部分配列の全要素の合計をmで割った余りを計算し、その中で最大の値を求めます。 具体例で問題を確認しよう まずは例を見て、問題の内容を理解しましょう。 入力 − array = {4, 9, 2}、m = 6 出力 − 5 説明 − すべての部分配列と、それぞれを6で割った余りは以下の通りです。 {4}: 4 % 6 = 4 {9}: 9 % 6 = 3 {2}: 2 % 6 = 2 {4, 9}

  2. C++で解く三角形の最小パス和:動的計画法による効率的なアプローチ

    問題概要 数値が三角形状に配置された構造が与えられます。頂点から最下段まで移動する際、各ステップで「下の行の隣接する数値」にのみ移動できるものとします。このとき、通過する数値の合計が最小となる経路の和を求めてください。 例 入力が以下の場合を考えます。     5   7 3  8 1 2 9 6 4 5 このとき最小の合計は 13 となり、その経路は次のとおりです。 5 + 3 + 1 + 4 アルゴリズム 動的計画法(DP)のメモ化テクニックを利用します。 メモ化用として、1次元配列 memorization を