0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[競プロ][Python] collections.Counter活用術

Posted at

Pythonのcollections.Counterは、競技プログラミングで利用できる強力なツールです。以下のようなパターンでよく使用されます。

要素の頻度計算

与えられた配列や文字列内で、各要素の出現回数を簡単にカウントできます。

例題:
配列内で最も頻度が高い要素を見つける。重複した要素を探す。

from collections import Counter

arr = [1, 2, 2, 3, 3, 3, 4]
counter = Counter(arr)
most_common = counter.most_common(1)[0]  # [(要素, 出現回数)]のリスト
print(most_common)  # 出力: (3, 3)

アナグラム判定

2つの文字列がアナグラム(文字の並べ替えで一致)かどうかを確認します。

例題:
入力された2つの文字列がアナグラムかどうかを判定。

from collections import Counter

s1 = "listen"
s2 = "silent"

if Counter(s1) == Counter(s2):
    print("アナグラム")
else:
    print("アナグラムではない")

条件付きの頻度チェック

一定の条件を満たす頻度の要素を抽出するパターン。

例題:
配列内でk回以上出現する要素を抽出。

from collections import Counter

arr = [1, 1, 2, 2, 2, 3, 4, 4, 5]
k = 2
counter = Counter(arr)
result = [key for key, count in counter.items() if count >= k]
print(result)  # 出力: [1, 2, 4]

多重集合の操作

複数のリストの要素間で和・積・差を計算できます。

例題:
2つのリストの共通部分や差分を求めるパターン。

from collections import Counter

list1 = [1, 2, 2, 3]
list2 = [2, 3, 3, 4]

counter1 = Counter(list1)
counter2 = Counter(list2)

# 共通部分
intersection = counter1 & counter2
print(list(intersection.elements()))  # 出力: [2, 3]

# 差分
difference = counter1 - counter2
print(list(difference.elements()))  # 出力: [1, 2]

頻度のカウントで分類

出現回数に基づいて要素をグループ化するパターン。

例題:
要素を頻度ごとに分類。

from collections import Counter

arr = [1, 1, 2, 2, 2, 3, 4, 4]
counter = Counter(arr)
grouped = {freq: [key for key, count in counter.items() if count == freq] for freq in set(counter.values())}
print(grouped)  # 出力: {2: [1, 4], 3: [2], 1: [3]}

スライディングウィンドウでの使用

ウィンドウ内の要素頻度を動的に管理するパターン。

例題:
部分配列内の要素頻度を効率的にカウント。

from collections import Counter

arr = [1, 2, 2, 3, 3, 3, 4]
k = 3

window_counter = Counter(arr[:k])
print(window_counter)  # 最初のウィンドウの頻度

for i in range(k, len(arr)):
    window_counter[arr[i - k]] -= 1  # 古い要素を削除
    if window_counter[arr[i - k]] == 0:
        del window_counter[arr[i - k]]  # 0になったら削除
    window_counter[arr[i]] += 1  # 新しい要素を追加
    print(window_counter)  # 各ウィンドウの頻度

辞書順での頻度カウント

頻度が同じ場合、要素を辞書順にソートして出力します。

例題:
頻度順、かつ同頻度の場合は辞書順に並べる。

from collections import Counter

arr = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counter = Counter(arr)

# 頻度順、同頻度なら辞書順
sorted_result = sorted(counter.items(), key=lambda x: (-x[1], x[0]))
print(sorted_result)  # 出力: [('apple', 3), ('banana', 2), ('cherry', 1)]

まとめ

これらのパターンを理解しておくことで、競技プログラミングの問題で効率的に活用できます。特に、データの頻度分析や集合演算に役立ちます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?