Pythonで2つのリストの要素間の最小差を求めるプログラム
2つのリスト間の最小差とは
2つのリスト L1 と L2 が与えられたとき、L1 のある要素と L2 のある要素を組み合わせたときに生じる「差」の中で、最も小さいもの(絶対値が最小となる差)を求める問題です。
例えば、入力が L1 = [2, 7, 4]、L2 = [16, 10, 11] の場合、出力は 3 になります。これは、10 − 7 = 3 という差が最も小さいためです。
解法のアプローチ:ソート+双方向ポインタ
この問題は、両方のリストをソートしてから、2つのポインタを使って効率的に比較していくことで解けます。手順は以下の通りです。
- リスト L1 をソートし、リスト L2 もソートする
- ans := 無限大(初期値)
- i := 0、j := 0 とする
- i が L1 のサイズ未満、かつ j が L2 のサイズ未満である間、以下を繰り返す
- ans := ans と |L1[i] − L2[j]| の小さい方を代入
- L1[i] < L2[j] の場合は i := i + 1
- そうでなければ j := j + 1
- ans を返す
このアルゴリズムでは、小さい方の要素のポインタを進めることで、常に「今考えうる最小差」を見逃さずにチェックできます。計算量はソートに O(n log n)、比較部分は O(n + m) となり、全組み合わせを総当たりする O(n × m) よりも大幅に高速です。
実装例
以下はPythonでの実装例です。
class Solution:
def solve(self, L1, L2):
L1.sort()
L2.sort()
ans = float("inf")
i = j = 0
while i < len(L1) and j < len(L2):
ans = min(ans, abs(L1[i] - L2[j]))
if L1[i] < L2[j]:
i += 1
else:
j += 1
return ans
ob = Solution()
L1 = [2, 7, 4]
L2 = [16, 10, 11]
print(ob.solve(L1, L2))
入力
[2, 7, 4], [16, 10, 11]
出力
3
コードのポイント
この実装における重要なポイントは次のとおりです。
- float("inf"):無限大を初期値として使うことで、最初の比較で必ず実際の差に置き換わります。
- abs() 関数:差の絶対値を取ることで、どちらのリストの要素が大きい場合でも正しく最小差を求められます。
- ポインタの進め方:より小さい側のポインタを進めることで、差が縮まる可能性のあるペアだけを効率的に調べます。
-
【Python入門】2つの文字列から珍しい単語(ユニークな単語)を見つけるプログラムの作り方
はじめに この記事では、以下の問題文に対する解決方法を、実際のコード例とともにわかりやすく解説します。 問題文 2つの文字列が与えられたとき、その中から「珍しい単語」(どちらか一方の文字列にしか出現しない単語)をすべて抽出することを目標とします。両方の文字列に共通して含まれる単語は除外します。 解決のアプローチ ここでは辞書(dict)を使った出現回数のカウント方式を採用します。手順は次のとおりです。 空の辞書を用意する 各文字列をsplit()で単語ごとに分割する 各単語の出現回数を辞書に記録する 出現回数がちょうど1回の単語だけを結果として返す 実装例 # 珍しい単語を見つける関
-
【初心者向け】Pythonで2つのリストの差分(違い)を抽出する方法を解説
この記事では、2つのリストが与えられたときに、その差分(違い)を表示するPythonプログラムを紹介します。Pythonにはset()メソッドが用意されており、ここではこのメソッドを活用します。 セット(集合)とは、重複する要素を持たない順序なしのコレクションです。セットオブジェクトは、和集合・積集合・差集合・対称差といった数学的な操作もサポートしているため、リスト同士の比較に非常に便利です。 実行例 入力: A = [10, 15, 20, 25, 30, 35, 40] B = [25, 40, 35] 出力: [10, 20, 30, 15] 考え方 求めたい差分リストは、次のよう