π― 1. Counter μ€μ ν¨ν΄ βββ
ν¨ν΄ 1: κ°μ₯ λ§μ΄/μ κ² λ±μ₯νλ μμ
from collections import Counter
arr = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
counter = Counter(arr)
# κ°μ₯ λ§μ μμ 1κ°
most_common = counter.most_common(1)
print(most_common) # [(4, 4)]
element, count = most_common[0]
print(f"{element}μ΄(κ°) {count}λ²") # 4μ΄(κ°) 4λ²
# κ°μ₯ λ§μ μμ 3κ°
top_3 = counter.most_common(3)
print(top_3) # [(4, 4), (3, 3), (2, 2)]
# κ°μ₯ μ μ μμ
least_common = counter.most_common()[-1]
print(least_common) # (1, 1)
# λλ
least_common = min(counter.items(), key=lambda x: x[1])
print(least_common) # (1, 1)
ν¨ν΄ 2: λ±μ₯ νμ 쑰건 νν°λ§
from collections import Counter
arr = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
counter = Counter(arr)
# 2λ² μ΄μ λ±μ₯ν μμ
duplicates = [num for num, count in counter.items() if count >= 2]
print(duplicates) # [2, 3, 4, 5]
# μ νν 1λ²λ§ λ±μ₯ν μμ
unique = [num for num, count in counter.items() if count == 1]
print(unique) # [1]
# 3λ² μ΄μ λ±μ₯ν μμμ κ°μ
count_3_plus = sum(1 for count in counter.values() if count >= 3)
print(count_3_plus) # 3 (3, 4, 5)
# κ°μ₯ λ§μ΄ λ±μ₯ν νμμ κ°μ μμλ€
max_count = max(counter.values())
most_frequent = [num for num, count in counter.items() if count == max_count]
print(most_frequent) # [5]
ν¨ν΄ 3: λ¬Έμμ΄ μλκ·Έλ¨ μ²΄ν¬
from collections import Counter
def is_anagram(s1, s2):
"""λ λ¬Έμμ΄μ΄ μλκ·Έλ¨μΈμ§ νμΈ"""
return Counter(s1) == Counter(s2)
print(is_anagram("listen", "silent")) # True
print(is_anagram("hello", "world")) # False
# 곡백/λμλ¬Έμ 무μ μλκ·Έλ¨
def is_anagram_ignore(s1, s2):
s1 = s1.lower().replace(' ', '')
s2 = s2.lower().replace(' ', '')
return Counter(s1) == Counter(s2)
print(is_anagram_ignore("A gentleman", "Elegant man")) # True
print(is_anagram_ignore("Conversation", "Voices rant on")) # True
ν¨ν΄ 4: μλκ·Έλ¨ κ·Έλ£Ήν βββ
from collections import defaultdict, Counter
def group_anagrams(words):
"""
κ°μ μλκ·Έλ¨λΌλ¦¬ κ·Έλ£Ήν
LeetCode 49: Group Anagrams
"""
groups = defaultdict(list)
for word in words:
# μ λ ¬λ λ¬Έμμ΄μ ν€λ‘ μ¬μ©
key = ''.join(sorted(word))
groups[key].append(word)
return list(groups.values())
words = ["eat", "tea", "tan", "ate", "nat", "bat"]
print(group_anagrams(words))
# [['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]
# Counterλ₯Ό μ¬μ©ν λ°©λ² (λ μ ν)
def group_anagrams_v2(words):
groups = defaultdict(list)
for word in words:
# Counterλ₯Ό ννλ‘ λ³ννμ¬ ν€λ‘ μ¬μ©
key = tuple(sorted(Counter(word).items()))
groups[key].append(word)
return list(groups.values())
ν¨ν΄ 5: κ°μ₯ λ§μ΄ λ±μ₯ν kκ° μμ βββ
from collections import Counter
import heapq
def top_k_frequent(nums, k):
"""
LeetCode 347: Top K Frequent Elements
"""
counter = Counter(nums)
# λ°©λ² 1: most_common μ¬μ© (κ°μ₯ κ°λ¨)
return [num for num, count in counter.most_common(k)]
print(top_k_frequent([1, 1, 1, 2, 2, 3], 2)) # [1, 2]
print(top_k_frequent([1], 1)) # [1]
# λ°©λ² 2: ν μ¬μ© (O(n log k))
def top_k_frequent_heap(nums, k):
counter = Counter(nums)
return heapq.nlargest(k, counter.keys(), key=counter.get)
ν¨ν΄ 6: Counter μ°μ μ°μ° βββ
from collections import Counter
c1 = Counter(['a', 'b', 'c', 'a', 'b'])
c2 = Counter(['a', 'b', 'd', 'd'])
# λ§μ
: ν©μΉκΈ°
print(c1 + c2)
# Counter({'a': 3, 'b': 3, 'd': 2, 'c': 1})
# λΊμ
: μ°¨μ§ν© (μμ/0 μ μΈ)
print(c1 - c2)
# Counter({'a': 1, 'c': 1, 'b': 1})
# κ΅μ§ν©: μ΅μκ°
print(c1 & c2)
# Counter({'a': 1, 'b': 1})
# ν©μ§ν©: μ΅λκ°
print(c1 | c2)
# Counter({'a': 2, 'b': 2, 'd': 2, 'c': 1})
# νμ©: μμ£Όνμ§ λͺ»ν μ μ
def solution(participant, completion):
return list((Counter(participant) - Counter(completion)).keys())[0]
π― 2. defaultdict μ€μ ν¨ν΄ βββ
ν¨ν΄ 1: κ·Έλν νν (κ°μ₯ λ§μ΄ μ!) βββ
from collections import defaultdict
# μΈμ 리μ€νΈλ‘ κ·Έλν νν
graph = defaultdict(list)
edges = [(1, 2), (1, 3), (2, 4), (3, 4), (4, 5)]
# 무방ν₯ κ·Έλν
for a, b in edges:
graph[a].append(b)
graph[b].append(a)
print(dict(graph))
# {1: [2, 3], 2: [1, 4], 3: [1, 4], 4: [2, 3, 5], 5: [4]}
# μ λ°©ν₯ κ·Έλν
directed_graph = defaultdict(list)
for a, b in edges:
directed_graph[a].append(b)
print(dict(directed_graph))
# {1: [2, 3], 2: [4], 3: [4], 4: [5]}
# κ°μ€μΉ κ·Έλν
weighted_graph = defaultdict(list)
edges_with_weight = [(1, 2, 5), (1, 3, 3), (2, 4, 2)]
for a, b, weight in edges_with_weight:
weighted_graph[a].append((b, weight))
weighted_graph[b].append((a, weight))
print(dict(weighted_graph))
# {1: [(2, 5), (3, 3)], 2: [(1, 5), (4, 2)], 3: [(1, 3)], 4: [(2, 2)]}
ν¨ν΄ 2: κ·Έλ£Ήν (μΉ΄ν
κ³ λ¦¬λ³ λΆλ₯) βββ
from collections import defaultdict
# νμ λ°μ΄ν°λ₯Ό νλ
λ³λ‘ κ·Έλ£Ήν
students = [
('Alice', 1, 85),
('Bob', 2, 90),
('Charlie', 1, 78),
('David', 2, 88),
('Eve', 3, 92)
]
# νλ
λ³ κ·Έλ£Ήν
by_grade = defaultdict(list)
for name, grade, score in students:
by_grade[grade].append((name, score))
print(dict(by_grade))
# {1: [('Alice', 85), ('Charlie', 78)],
# 2: [('Bob', 90), ('David', 88)],
# 3: [('Eve', 92)]}
# μ μλλ³ κ·Έλ£Ήν
by_score_range = defaultdict(list)
for name, grade, score in students:
score_range = (score // 10) * 10 # 80μ λ, 90μ λ λ±
by_score_range[score_range].append(name)
print(dict(by_score_range))
# {80: ['Alice', 'David'], 90: ['Bob', 'Eve'], 70: ['Charlie']}