C++で長さkの部分文字列に含まれる母音の最大数を求める方法
文字列 s と整数 k が与えられたとき、長さがちょうど k である s の部分文字列の中に、母音(a, e, i, o, u)が最大でいくつ含まれるかを求める問題です。
例えば、入力が s = "abciiidef"、k = 3 の場合、出力は 3 になります。これは、部分文字列 "iii" に母音が3つ含まれているためです。
解法アプローチ:スライディングウィンドウ(尺取り法)
この問題は「スライディングウィンドウ」と呼ばれる手法を使うことで、文字列全体を一度走査するだけで効率的に解くことができます。各ステップでウィンドウの右端に新しい文字を追加し、左端から古い文字を取り除くことで、毎回母音を数え直す無駄を省きます。
具体的な手順は以下の通りです。
- 母音カウンター
cntを 0 で初期化する - 母音を格納するセット
mを定義し、a, e, i, o, u を挿入する - 結果を保持する変数
retを 0 で初期化する - 最初のウィンドウ(先頭から k 文字)に含まれる母音の数を数えて
cntに加算する retとcntの大きい方をretに代入する- 文字列の長さを
nとする iを k から n-1 まで増やしながら以下を繰り返す- ウィンドウから外れる文字
s[i-k]が母音ならcntを1減らす - ウィンドウに入る文字
s[i]が母音ならcntを1増やす retとcntの大きい方をretに代入する
- ウィンドウから外れる文字
- 最後に
retを返す
C++での実装例
それでは、実際のコードを見て理解を深めましょう。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int maxVowels(string s, int k) {
int cnt = 0;
set<char> m;
for (auto it : { 'a', 'e', 'i', 'o', 'u' })
m.insert(it);
int ret = 0;
for (int i = 0; i < k; i++) {
cnt += m.count(s[i]) ? 1 : 0;
}
ret = max(ret, cnt);
int n = s.size();
for (int i = k; i < n; i++) {
if (m.count(s[i - k])) {
cnt--;
}
cnt += m.count(s[i]) ? 1 : 0;
ret = max(ret, cnt);
}
return ret;
}
};
main(){
Solution ob;
cout << (ob.maxVowels("abciiidef",3));
}入力
"abciiidef", 3
出力
3
計算量の分析
- 時間計算量: O(n) ― 文字列を一度だけ走査すればよいため、非常に高速です。
- 空間計算量: O(1) ― 母音のセットは固定サイズ(5要素)であり、追加のメモリはほとんど不要です。
もし素朴なアプローチ(すべての長さ k の部分文字列に対して毎回母音を数え直す)を採用すると、時間計算量は O(n × k) になってしまいます。スライディングウィンドウを使うことで、これを O(n) まで大幅に改善できるのがこの手法の大きな利点です。
-
二分木で屈曲数が最大となるパスの長さを求めるC++プログラム
本記事では、二分木が与えられたときに、屈曲数が最大となるパスを求める問題を解いていきます。ここで「屈曲(ベンド)」とは、パスの進行方向が左から右へ、または右から左へと切り替わる箇所のことです。具体例を見てみましょう。入力 −出力 −6この方法では、木を走査しながら直前の移動方向を記録していきます。方向が変化した時点で屈曲数を加算し、最終的にその最大値を求めます。解法のアプローチこのアプローチでは、すべてのパスを辿り、各パスにおける屈曲の総数を計算します。葉ノードに到達した時点で、これまでの屈曲数が現在の最大値を上回っていれば、答えとパスの長さを新しい値に更新します。C++による実装例#incl
-
C++で指定された数がプロニック数(Pronic Number)かどうかを判定する方法
プロニック数(Pronic Number)とは、点を長方形の形にきれいに配置できる数のことで、「矩形数」と呼ばれることもあります。その定義は非常にシンプルで、2つの連続する整数の積として表される数です。つまり、プロニック数 n は次の式で表せます。n = x × (x + 1)最初のいくつかのプロニック数を列挙すると、0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342 となります。プロニック数の具体例2 = 1 × 26 = 2 × 312 = 3 × 420 = 4 × 530 =