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

Pythonで左右の要素の合計が等しいインデックスを見つけるプログラム

リスト nums が与えられたとき、「あるインデックス i の左側にある要素の合計」と「右側にある要素の合計」が等しくなるような、最小のインデックス i を求めることを考えます。該当するインデックスが存在しない場合は -1 を返します。

例えば、入力が nums = [8,2,3,6,5,2,5,9,1,2] の場合、出力は 4 となります。これは、インデックス 4 の左側の要素 [8,2,3,6] の合計が 19、右側の要素 [2,5,9,1,2] の合計も 19 となり、両者が一致するためです。

解法のアプローチ

この問題を効率的に解くには、リスト全体の合計をあらかじめ計算しておき、左から順に走査しながら「右側の残りの合計」と「左側の累積合計」を比較していく方法が有効です。手順は以下の通りです。

  • 変数 r に nums の全要素の合計を代入します
  • 変数 l を 0 で初期化します
  • enumerate() を使って、各インデックス i と値 x を順に処理します
    • r から x を引きます(これで現在位置より右側の合計になります)
    • r と l が等しければ、i を返します
    • l に x を加えます(次の位置のための左側の合計を更新)
  • ループが終了しても条件を満たすインデックスが見つからなければ、-1 を返します

実装例

以下に Python での実装例を示します。

def solve(nums):
   r = sum(nums)
   l = 0
   for i,x in enumerate(nums):
      r -= x
      if r == l:
         return i
      l += x
   return -1

nums = [8,2,3,6,5,2,5,9,1,2]
print(solve(nums))

入力

[8,2,3,6,5,2,5,9,1,2]

出力

4

アルゴリズムのポイント

この手法では、各インデックスごとに左右の合計を毎回再計算する必要がないため、時間計算量は O(n)、追加のメモリ使用量は O(1) で済みます。全要素の合計を先に求めておき、走査中に右側の合計を減算しながら左側の合計を加算していくことで、たった 1 回のループで答えを導き出せるのが大きなポイントです。素朴な 2 重ループによる O(n²) の解法と比べて、大規模なデータでも高速に動作します。

  1. Pythonで二分木のノードとその子孫の最大絶対差を求めるプログラム

    問題概要 二分木が与えられたとき、任意のノードとその子孫との間の絶対差の最大値を求めることを考えます。 例えば、次のような二分木が入力として与えられた場合を考えてみましょう。 この場合、ノード8とノード1の間の差が最も大きくなるため、出力は 7 となります。 解法のアプローチ:DFSを使った追跡 この問題は、DFS(深さ優先探索)を用いることで効率的に解けます。各ノードについて「その部分木内の最小値」と「最大値」を追跡しながら、現在のノードの値との差を順次更新していくのがポイントです。 具体的な手順は以下の通りです。 dfs() 関数を定義します。引数としてノードを受け取ります。 ノード

  2. Pythonで二分木の全ノードの値の合計を求めるプログラム

    二分木(バイナリツリー)にいくつかの値が格納されている場合、木に含まれるすべての値の合計を求めたいことがあります。例えば、次のような二分木が入力として与えられたとします。この場合、出力は 14 になります(2 + 4 + 3 + 5 = 14)。解決のアプローチこの問題を解くには、再帰を使って各ノードを順番に訪問し、値を足し合わせていきます。具体的な手順は以下の通りです。関数 recurse() を定義します。引数としてノードを受け取ります。変数 val に現在のノードの値を代入します。ノードの左の子が存在する場合は、val に左部分木の再帰結果を加算します。ノードの右の子が存在する場合は、v