サイズKの部分配列のうち平均が閾値以上になる個数をC++で求める方法
整数型の配列 arr と、2つの整数 k および threshold が与えられます。このとき、サイズが k で平均が threshold 以上となる部分配列(サブアレイ)の個数を求めるのが目的です。
例として、入力が [2,2,2,2,5,5,5,8]、k = 3、threshold = 4 の場合を考えてみましょう。このとき出力は 3 になります。これは、部分配列 [2,5,5]、[5,5,5]、[5,5,8] の平均がそれぞれ 4、5、6 となり、いずれも閾値 4 以上だからです。
解法のアプローチ(スライディングウィンドウ)
この問題は、スライディングウィンドウ(尺取り法)を使えば効率的に解けます。ウィンドウ内の合計値を管理し、要素を1つずつずらしながら平均を判定していくことで、配列を一度走査するだけで答えが求まります。
具体的な手順は以下の通りです。
sum := 0、div := k、n := 配列の要素数とするsumに配列arrの先頭k個の要素の合計を代入するret := 0(答えを格納する変数)で初期化するi := 0、jをkからn - 1の範囲で、iとjを同時に1ずつ増やしながら繰り返すsum / div >= thresholdであればretを1増やすsumからarr[i]を引く(ウィンドウの左端を除外)sumにarr[j]を足す(ウィンドウの右端を追加)
- ループ終了後、最後のウィンドウに対して
sum / div >= thresholdであればretを1増やす retを返す
この方法では、各ウィンドウの合計を毎回再計算する必要がなく、差分のみを更新するため、時間計算量は O(n)、空間計算量は O(1) で済みます。
C++による実装例
以下に、実際の実装例を示します。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int numOfSubarrays(vector<int>& arr, int k, int threshold) {
double sum = 0;
double div = k;
int n = arr.size();
for(int i = 0; i < k; i++){
sum += arr[i];
}
int ret = 0;
for(int i = 0, j = k; j < n; i ++, j++){
if(sum / div >= threshold ){
ret++;
}
sum -= arr[i];
sum += arr[j];
}
if(sum / div >= threshold ){
ret++;
}
return ret;
}
};
main(){
vector<int> v = {2,2,2,2,5,5,5,8};
Solution ob;
cout << (ob.numOfSubarrays(v, 3, 4));
}入力
[2,2,2,2,5,5,5,8] 3 4
出力
3
この実装では、最初にサイズ k のウィンドウの合計を計算し、その後ウィンドウを1つずつ右にずらしながら条件を判定しています。最後のウィンドウはループ内で判定されないため、ループ後に個別にチェックしている点に注意してください。
-
C++を使って「数x + xの桁の合計 = n」となる数xを求める方法
ここでは、ある数nが与えられたとき、「数xとその桁の合計を足した値がnと等しくなる」ようなxを求める問題を扱います。例えば、nが21の場合、答えはx = 15となります。15の桁の合計は1 + 5 = 6なので、15 + 6 = 21 = nとなり、条件を満たすからです。この問題を解くには、シンプルなアプローチが有効です。0からnまでの数を順番に調べていき、各数値について「その数 + 桁の合計」がnと一致するかどうかを確認します。一致する数が見つかった時点でその値を返し、最後まで見つからなければ-1を返します。サンプルコード#include<iostream> using name
-
C++で「x + 桁の合計 = n」を満たす数xを見つける方法
この記事では、ある整数 n が与えられたとき、「x + x の各桁の合計 = n」という条件を満たす数 x を求める問題を解説します。例として、n = 21 の場合を考えてみましょう。このとき答えは x = 15 となります。なぜなら、15 の各桁の合計は 1 + 5 = 6 であり、15 + 6 = 21 となって、与えられた n と一致するからです。解き方のアプローチこの問題はシンプルな方法で解くことができます。1 から n まで順番に数を調べていき、それぞれの数について「その数自身 + 各桁の合計」が n と等しくなるかどうかを確認します。条件を満たす数が見つかった時点で処理を終了し、そ