Pythonで配列内の同一要素インデックスペア(i < j)を効率的にカウントする方法
問題概要
数値のリスト nums が与えられたとき、i < j を満たし、かつ nums[i] と nums[j] が等しいようなインデックスのペア (i, j) の個数を求めることを考えます。
たとえば、入力が nums = [5, 4, 5, 4, 4] の場合、出力は 4 になります。これは、(0, 2)、(1, 3)、(1, 4)、(3, 4) の4つのインデックスペアが条件を満たすためです。
解法のアプローチ
この問題は、各値の出現回数を集計してから組み合わせの数を足し合わせることで、効率的に解くことができます。手順は以下の通りです。
- Python標準ライブラリの Counter を使い、nums 内の各要素の出現回数を集計します。
- 変数 count を 0 に初期化します。
- 各要素の出現回数 n に対して、count に n × (n − 1) / 2 を加算します。
- 最終的な count を返します。
なぜ n × (n − 1) / 2 なのか?
ある値が n 回出現する場合、その中から2つのインデックスを選ぶ組み合わせの総数は、二項係数 C(n, 2) = n × (n − 1) / 2 で表されます。この公式を使うことで、各値ごとのペア数を一括して計算でき、全体的な計算量は O(N) に抑えられます。全ペアを素朴に二重ループで調べる O(N²) の方法よりも大幅に高速です。
実装例
以下のコードで実際の動作を確認してみましょう。
from collections import Counter
def solve(nums):
c = Counter(nums)
count = 0
for n in c.values():
count += n * (n - 1) // 2
return count
nums = [5, 4, 5, 4, 4]
print(solve(nums))入力
[5, 4, 5, 4, 4]
出力
4
-
Pythonで配列の反転数(転倒数)をカウントする方法
はじめに この記事では、配列内の反転(インバージョン)をカウントする問題とその解決策について詳しく解説します。 問題定義 問題: リストが与えられたとき、その中に含まれる反転の数をカウントして表示します。 反転数とは、配列を昇順にソートされた状態にするために必要な入れ替え(スワップ)の回数を表す指標です。具体的には、i < j かつ arr[i] > arr[j] を満たす要素のペア(i, j)の総数として定義されます。 実装例 # 反転数をカウントする関数 def InvCount(arr, n): inv_count = 0 for i in range(n
-
Pythonでアナグラム部分文字列検索プログラムを作成する方法
はじめに この記事では、以下の問題文に対する解決策について学びます。 問題文 − テキストとパターンが与えられたとき、テキスト内に含まれるパターンおよびその順列(アナグラム)の出現位置をすべて出力します。 例えば、テキストが「TUTORIALSPOINT」、パターンが「TOR」であれば、「ROT」や「OTR」といった並べ替えも検索対象となります。 アルゴリズムの考え方 この問題は、スライディングウィンドウ(滑動窓)と文字カウント配列を組み合わせることで効率的に解くことができます。手順は以下のとおりです。 パターン内の各文字の出現回数を、カウント配列 countP に記録します。 テキストの先