Pythonで配列から和がKになるペアを最大限取り除く方法を解説
問題の概要
nums という整数の配列と、もう一つの値 k が与えられます。1 回の操作では、合計が k に等しくなる 2 つの要素を nums から選び、それらを配列から取り除くことができます。ここでの課題は、この操作を実行できる最大回数を求めることです。
たとえば、入力が nums = [8,3,6,1,5]、k = 9 の場合、答えは 2 になります。これは、まず合計が 9 になる [3,6] を削除でき、その後同じく合計が 9 になる [8,1] も削除できるためです。残った要素は [5] だけとなり、これ以上操作は行えません。
解決のアプローチ
この問題は、各値の出現回数をカウントしながらペアを探していくことで効率的に解けます。手順は以下の通りです。
- まず、nums 内の各要素の出現頻度を保持するマップ(counter)を作成します。
- 結果を格納する変数 res を 0 で初期化します。
- counter 内の各値 num について、以下を判定します。
- 補完値である
k - numが counter 内に存在する場合:- num が k - num と異なる場合(例:num=3、k-num=6):両方のカウントのうち小さい方がペアとして成立するので、その最小値を res に加算し、両方のカウントを 0 にリセットします。
- num が k - num と等しい場合(例:k=10、num=5):同じ値同士でペアを組むため、カウントを 2 で割った商がペアの数になります。
- 補完値である
- 最終的に res を返します。
この方法なら、各要素を一度だけ走査すればよいため、時間計算量は O(n)、空間計算量も O(n) で済みます。
実装例
理解を深めるために、実際のコードを見てみましょう。
from collections import Counter
def solve(nums, k):
counter = Counter(nums)
res = 0
for num in counter:
if counter.get(k - num, 0):
if num != k - num:
res += min(counter[num], counter[k - num])
counter[k - num] = 0
counter[num] = 0
else:
res += int(counter[num] / 2)
return res
nums = [8, 3, 6, 1, 5]
k = 9
print(solve(nums, k))
コードのポイント
collections.Counter を使うことで、配列内の各値の出現頻度を一行で取得できます。counter.get(k - num, 0) により、対応する補完値が存在しない場合でもエラーにならず安全に処理できます。また、ペアとして使用した値は必ずカウントを 0 にしているため、同じペアを二重に数えてしまう心配がありません。
入力例
[8, 3, 6, 1, 5], 9
出力例
2
このように、Counter を活用した頻度管理により、和が k になるペアの最大削除回数をシンプルかつ効率的に求めることができます。
-
Pythonで二分探索木(BST)の指定範囲内にあるノード数を求める方法
問題の概要 二分探索木(BST)が与えられ、さらに左側の境界値 l と右側の境界値 r が指定されます。このとき、木に含まれるすべてのノードの中で、値が l 以上 r 以下の範囲内にあるノードの個数を求めるのが目的です。 例えば、次のような木が与えられたとします。 このとき l = 7、r = 13 とすると、範囲内に含まれるノードは 8、10、12 の3つなので、出力は 3 になります。 アルゴリズムの考え方 スタックを使った反復的な深さ優先探索(DFS)で木をたどります。重要なポイントは、二分探索木の性質を活かして枝刈り(pruning)を行うことです。値が境界より小さいノードの左側の
-
Pythonでリスト内の最小値を見つける方法を解説
この記事では、リストの中から最小の数値を見つける方法について、具体的なサンプルコードとともに詳しく解説します。問題の概要問題: 数値のリストが与えられたとき、その中に含まれる最も小さい数値を画面に表示すること。この問題を解くアプローチは主に2つあります。ひとつは sort() メソッドを使ってリストを昇順に並べ替え、先頭の要素(インデックス0)を取得する方法。もうひとつは、Pythonに標準で用意されている組み込み関数 min() を使う方法です。それぞれ順番に見ていきましょう。方法1:sort()メソッドで並べ替えて最小値を取得するまずはリストを昇順にソートし、先頭の要素を取り出す方法です。