Pythonでバイナリリスト内の合計がkとなるサブリストの個数を求めるプログラム
問題の概要
0と1のみで構成されるバイナリリストが与えられたとします。さらに別の入力として整数 k が与えられ、要素の合計がちょうど k に一致するサブリスト(連続する部分配列)の個数を求める必要があります。
例えば、入力が nums = [1, 0, 0, 1, 1, 1, 0, 1]、k = 3 の場合、出力は 8 になります。これは、条件を満たすサブリストとして [1,0,0,1,1]、[0,0,1,1,1]、[0,0,1,1,1,0]、[0,1,1,1]、[0,1,1,1,0]、[1,1,1]、[1,1,1,0]、[1,1,0,1] の8つが存在するためです。
解決のためのアプローチ
この問題は「累積和」と「ハッシュマップ(辞書)」を組み合わせることで効率的に解けます。リストを走査しながら各位置までの累積和を記録し、「現在の累積和 − k」という値がこれまでに何回出現したかを数えることで、合計が k になるサブリストの数を求めます。手順は以下の通りです。
- sums := キー 0 に値 1 を持つマップ(辞書)で初期化する
- r_sum := 0(累積和を保持する変数)
- ans := 0(答えを保持する変数)
- nums の各要素 x に対して以下を繰り返す
- r_sum := r_sum + x(累積和を更新)
- ans := ans +(r_sum − k が sums に存在すればその値、なければ 0)
- sums[r_sum] := 現在の値 + 1(累積和の出現回数をカウントアップ)
- 最後に ans を返す
この手法により、すべてのサブリストを総当たりする O(n²) の方法に比べて、線形時間 O(n) で処理が完了します。
実装例
理解を深めるために、以下のPythonコードを見てみましょう。
def solve(nums, k):
sums = {0: 1}
r_sum = 0
ans = 0
for x in nums:
r_sum += x
ans += sums.get(r_sum - k, 0)
sums[r_sum] = sums.get(r_sum, 0) + 1
return ans
nums = [1, 0, 0, 1, 1, 1, 0, 1]
k = 3
print(solve(nums, k))入力
[1, 0, 0, 1, 1, 1, 0, 1], 3
出力
8
計算量について
このアルゴリズムの時間計算量は O(n)、空間計算量は O(n) です(n はリストの長さ)。累積和の出現回数を辞書で管理することで、各要素を一度だけ走査すればよいため、大規模なデータでも高速に動作します。
-
Pythonでリストの累積和(累積合計)を求める方法
この記事では、リストの累積和(累積合計)を求める問題の解決策について詳しく解説します。問題文あるリストが与えられたとき、各要素までの累積和を格納した新しいリストを作成する必要があります。例えば、[10, 20, 30, 40, 50] というリストが与えられた場合、出力は [10, 30, 60, 100, 150] となります。これは、各位置でそれ以前の要素をすべて足し合わせた値です。実装例それでは、実際の実装を見ていきましょう。# 累積和を求める関数 def Cumulative(l): new = [] cumsum = 0 for element in l:
-
リスト内の要素の合計を求めるPythonプログラム
この記事では、Pythonを使ってリスト内のすべての要素の合計を求める方法について、具体的なコード例とともに解説します。問題の定義リストが入力として与えられたとき、そのリストに含まれるすべての要素の合計値を計算する必要があります。例えば、[1, 2, 3, 4, 5]というリストが与えられた場合、出力は 15(1+2+3+4+5)となります。この問題を解くためのアプローチは主に2つあります。1つは組み込み関数を使用する方法、もう1つはブルートフォース(総当たり)方式でループ処理を行う方法です。方法1:組み込み関数 sum() を使うPythonには標準で用意されている組み込み関数 sum()