Pythonでターゲット未満となる最大のペア合計を求めるプログラム
問題の概要
数値のリスト nums とターゲット値 target が与えられたとします。このとき、合計がターゲット未満(target - 1 以下)となる2つの数値のペアの中から、最も大きな合計を見つける必要があります。
たとえば、入力が nums = [8, 3, 4, 9, 2]、target = 8 の場合、出力は 7 になります。これは、8 未満となる最大のペアの合計が 4 + 3 = 7 だからです。
解法のアプローチ
この問題は「ソート + 両端ポインタ(ツーポインタ法)」というテクニックを使うことで効率的に解けます。手順は以下のとおりです。
- リスト
numsを昇順にソートします。 - 左ポインタ
p1を 0、右ポインタp2をリストの末尾(サイズ − 1)に設定します。 - 変数
mを負の無限大(-inf)で初期化します。 p1 < p2の間、以下を繰り返します。nums[p1] + nums[p2] < targetの場合:mを現在の合計と比較して大きい方で更新し、p1を1つ右へ進めます。- それ以外の場合:合計がターゲット以上なので、
p2を1つ左へ戻します。
- ループ終了後、
mを返します。
なぜこの方法が機能するのか
リストを事前にソートしておけば、両端から挟み込むように合計を調べることで、すべてのペアを総当たり(O(n²))せずとも最適な組み合わせを効率よく見つけられます。合計がターゲット以上なら右側の値を下げて合計を減らし、ターゲット未満ならその合計を候補として記録したうえで左側の値を上げていきます。
実装例
以下はPythonでの実装例です。
import math
def solve(nums, target):
nums.sort()
p1 = 0
p2 = len(nums) - 1
m = -math.inf
while p1 < p2:
if nums[p1] + nums[p2] < target:
m = max(m, nums[p1] + nums[p2])
p1 += 1
else:
p2 -= 1
return m
nums = [8, 3, 4, 9, 2]
target = 8
print(solve(nums, target))
入力
[8, 3, 4, 9, 2], 8
出力
7
計算量
ソートに O(n log n)、その後のポインタ走査に O(n) かかるため、全体の時間計算量は O(n log n) です。追加で必要なメモリは定数領域のみで済むため、非常に効率的な解法といえます。
-
Pythonで配列の合計を求める方法を徹底解説
この記事では、Pythonを使って配列(リスト)の合計を求める方法について詳しく解説します。 問題文 問題: 配列が与えられたとき、その配列に含まれるすべての要素の合計を計算してください。 最も基本的なアプローチは、配列全体を走査し、各インデックスの要素を順番に加算していく方法です。ここでは、まず組み込み関数を活用したシンプルな実装例を見ていきましょう。 方法1:組み込み関数 sum() を使う Pythonには、イテラブルなオブジェクトの合計を一発で計算できる組み込み関数 sum() が用意されています。これを使えば、コードは非常に簡潔になります。 サンプルコード # 合計を求める関数 de
-
Pythonで配列(リスト)の合計を求める方法をわかりやすく解説
この記事では、配列(リスト)の合計値を求めるという問題に対して、Pythonでの解決策とアプローチをわかりやすく解説します。 問題の定義 配列が入力として与えられたとき、その配列に含まれるすべての要素の合計を計算することを目標とします。 例えば、[1, 2, 3, 4, 5] という配列が与えられた場合、出力は 15 になります。 アプローチ1:ループを使った素朴な方法(総当たり法) 最も基本的な方法は、リストを先頭から順に走査し、各要素を合計用の変数に加算していくやり方です。手順は以下の通りです。 合計を格納する変数を 0 で初期化します。 for ループでリストの各要素を取り出し、順番に