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

平均がターゲット以上となる長さKのサブリストの数を求めるPythonプログラム

問題の概要

リスト nums と、2つの値 k および target が与えられたとします。このとき、「要素数がちょうど k であり、その平均値が target 以上であるサブリスト」の個数を求めるのが今回の課題です。

たとえば、入力が nums = [1, 10, 5, 6, 7]k = 3target = 6 の場合を考えてみましょう。このとき出力は 2 となります。サブリスト [1, 10, 7] の平均値は 6、サブリスト [10, 5, 6] の平均値は 7 となり、条件を満たすものが2つ存在するためです。

アルゴリズムの考え方

この問題は「スライディングウィンドウ(移動窓)」という手法を使うことで効率的に解くことができます。手順は以下の通りです。

  • 比較のたびに除算を行わないよう、あらかじめ target *= k として「合計値との比較」に置き換えます(平均 ≥ target ⟺ 合計 ≥ target × k)。
  • 合計を保持する変数 sum と、答えを格納する ans をそれぞれ 0 で初期化します。
  • リストの各要素 n(インデックス i)に対して以下を処理します。
    • i >= k のとき、ウィンドウから外れる要素 nums[i - k] を合計から減算します。
    • 現在の要素 n を合計に加算します。
    • i >= k - 1(ウィンドウが k 個分埋まった状態)のとき、sum >= target であれば ans を 1 増やします。
  • 最後に ans を返します。

実装例

それでは、以下のコードを見ながら理解を深めていきましょう。

サンプルコード

class Solution:
    def solve(self, nums, k, target):
        target *= k
        sum = 0
        ans = 0
        for i, n in enumerate(nums):
            if i >= k:
                sum -= nums[i - k]
            sum += n
            if i >= (k - 1):
                if sum >= target:
                    ans += 1
        return ans

ob = Solution()
nums = [1, 10, 5, 6, 7]
k = 3
target = 6
print(ob.solve(nums, k, target))

入力

[1, 10, 5, 6, 7], 3, 6

出力

2

計算量について

このアルゴリズムでは各要素を一度ずつ処理するため、時間計算量は O(n)、追加のメモリ使用量は O(1) で済みます。すべてのサイズ k のサブリストを毎回ゼロから合計し直す素朴な方法(O(n × k))と比べて大幅に効率的であり、大きなデータセットでも高速に動作する点がメリットです。

  1. Pythonで+と−を配置して合計をターゲット値に一致させる方法の数を求めるプログラム

    問題の概要 負でない整数のリスト nums と整数 target が与えられます。それぞれの要素に対して「+」または「-」の記号を割り当て、式全体の評価結果が target と一致するような配置が何通りあるかを求めます。 たとえば、入力が nums = [2, 3, 3, 3, 2]、target = 9 の場合、出力は 2 になります。条件を満たすのは次の2通りです。 -2 + 3 + 3 + 3 + 2 2 + 3 + 3 + 3 - 2 考え方:部分和問題への置き換え この問題は、動的計画法(DP)による「部分集合の数え上げ」として定式化できます。プラス記号を付けた要素の総和を P

  2. Pythonでstart値をend値に変換するための最小操作回数を求めるプログラム

    問題概要2つの整数 start と end が与えられたとき、次の2種類の操作のみを使って start を end に変換するために必要な最小の操作回数を求めます。値から 1 を引く(デクリメント)値に 2 を掛ける(倍にする)例として、start = 2、end = 7 の場合を考えてみましょう。このとき出力は 3 になります。具体的には、2 に 2 を掛けて 4 にし、さらに 2 を掛けて 8 にし、最後に 1 を引いて 7 にするという流れです。解き方のアプローチこの問題は、end 側から逆算していくことで効率的に解けます。start から end へ向かうのではなく、end を sta