Pythonでnums[i] = nums[j]となるペア(i, j)の個数を求めるプログラム
配列 nums が与えられたとき、nums[i] = nums[j] を満たし、かつ i ≠ j であるようなペア(i, j)の個数を求めることを考えます。
たとえば入力が nums = [1, 3, 1, 3, 5] の場合、出力は 4 になります。該当するペアは (0, 2)、(2, 0)、(1, 3)、(3, 1) の4つだからです。
解法のアプローチ
この問題は、各値の出現回数を集計してから組み合わせを計算することで、効率的に解くことができます。手順は以下の通りです。
- 出現回数を記録するための空の辞書(マップ)
dを用意する numsの各要素cについて、すでにdに存在すればカウントを +1、なければ 1 を設定する- 結果を格納する変数
resを 0 で初期化する - 出現回数が 2 回以上の各値
cに対して、res += d[c] * (d[c] - 1)を加算する resを返す
ある値が n 回出現するとき、インデックスの異なる順序付きペアの数は n × (n − 1) 通りになります。これは「n 個から異なる2つを選んで並べる」場合の数 P(n, 2) に相当します。
実装例
以下のコードで実際の動作を確認してみましょう。
def solve(nums):
d = {}
for c in nums:
d[c] = d[c] + 1 if c in d.keys() else 1
res = 0
for c in (x for x in d if d[x] > 1):
res += (d[c] * (d[c] - 1))
return res
nums = [1, 3, 1, 3, 5]
print(solve(nums))
入力
[1, 3, 1, 3, 5]
出力
4
計算量
このアルゴリズムは配列を一度走査してカウントし、その後辞書の要素を一度だけ走査するため、時間計算量は O(N)、追加で必要なメモリも O(N) です。全ペアを総当たりで調べる O(N²) の素朴な解法と比べて、大きな配列でも高速に処理できる点がメリットです。
-
Pythonで2つの異なるBST(二分探索木)から指定した合計値となるペアを検索する方法
2つの二分探索木(BST)とある合計値が与えられたとき、その合計値に一致するペアを探します。ただし、各ペアの要素は異なるBSTに属している必要があります。例として、sum = 12 が与えられた場合を考えてみましょう。この場合、出力は [(6, 6), (7, 5), (9, 3)] となります。解法のアプローチこの問題は、以下の手順で効率的に解くことができます。各木を中順走査(in-order traversal)して、昇順にソートされたリストを作成します。1つ目のリストは先頭(最小値)から、2つ目のリストは末尾(最大値)から両端ポインタ方式で走査します。2つの要素の合計が目標値と等しければ
-
【Python】行列の異なる行から指定した合計になるペアをすべて検索する方法
問題の概要ユニークな要素で構成される行列(マトリックス)と目標の合計値が与えられたとき、合計がその値と一致するすべてのペアを行列から見つけます。ただし、ペアを構成する2つの要素は、必ず異なる行から取得する必要があります。たとえば、次のような入力が与えられたとします。24356987101114121311516sum = 13 の場合、出力は次のようになります。[(4, 9), (5, 8), (2, 11), (3, 10), (12, 1)]アルゴリズムの手順この問題は、各行をあらかじめソートしておき、行の組み合わせごとにツーポインター法を用いて合計が一致するペアを効率よく探索します。手順