Pythonで合計がkに最も近い3つの異なる要素をリストから見つけるプログラム
この記事では、数値のリスト nums ともう一つの値 k が与えられたとき、|a + b + c − k| が最小になるようにリスト内の3つの異なる要素 (a, b, c) を選び、その絶対差を返す方法を解説します。
問題の例
たとえば、入力が nums = [2, 5, 25, 6]、k = 14 だった場合を考えてみましょう。[2, 5, 6] を選ぶと合計は13になり、14に最も近づきます。したがって絶対差は |13 − 14| = 1 となり、出力は 1 です。
解法のアプローチ(二ポインタ法)
この問題は、ソートと「二ポインタ」テクニックを組み合わせることで効率的に解けます。手順は以下の通りです。
- リスト
numsを昇順にソートする ansを十分大きな値(109)で初期化するiを 0 からlen(nums) - 1までループさせる- 左ポインタ
j := i + 1 - 右ポインタ
k := len(nums) - 1 j < kの間、以下を繰り返すs := nums[i] + nums[j] + nums[k]を計算するs <= targetの場合:ansをmin(ans, target − s)で更新し、j += 1として合計を大きくする方向へ進む- それ以外の場合:
ansをmin(ans, s − target)で更新し、k -= 1として合計を小さくする方向へ進む
- 左ポインタ
- 最後に
ansを返す
この手法により、全組み合わせを総当たり(O(n³))する必要がなくなり、時間計算量は O(n²) に抑えられます。
実装例(Pythonコード)
class Solution: def solve(self, nums, target): nums.sort() ans = 1e9 for i in range(len(nums)): j = i + 1 k = len(nums) − 1 while j < k: s = nums[i] + nums[j] + nums[k] if s <= target: ans = min(ans, target - s) j += 1 else: ans = min(ans, s - target) k −= 1 return ans ob1 = Solution() nums = [2, 5, 25, 6] k = 14 print(ob1.solve(nums, k))
入力
[2, 5, 25, 6], 14
出力
1
まとめ
リストをソートしてから固定の1要素に対して残りの範囲を左右のポインタで挟み込むことで、目的の合計に近づける要素の組み合わせを効率よく探索できます。目標値より合計が小さい場合は左ポインタを、大きい場合は右ポインタを動かすというシンプルな判断だけで、最適解に到達できるのがこのアルゴリズムのポイントです。
-
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()