Anagram dan Peta Frekuensi Karakter
Selesaikan group-anagrams, valid-anagram, dan permutation-in-string menggunakan array frekuensi serta hash map untuk solusi O(n).
Anagram dan Peta Frekuensi Karakter adalah pelajaran Coding Interview Prep gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Coding Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Coding Interview Prep mencakup 4 pelajaran total.
Apa Itu Anagram?
Dua teks disebut anagram jika keduanya berisi karakter yang sama dengan frekuensi yang sama, hanya urutannya berbeda. ‘batu’ dan ‘buat’ adalah anagram. Pemeriksaan kebenaran paling sederhana adalah mengurutkan kedua teks lalu membandingkannya: O(n log n). Untuk solusi O(n), bandingkan peta frekuensi karakter. Masalah anagram sering muncul dalam wawancara tentang teks karena menguji beberapa teknik: pencincangan, pengurutan, dan larik frekuensi.
def is_anagram_sort(s, t):
return sorted(s) == sorted(t) # O(n log n)
def is_anagram_counter(s, t):
from collections import Counter
return Counter(s) == Counter(t) # O(n)
def is_anagram_array(s, t):
if len(s) != len(t): return False
freq = [0] * 26
for a, b in zip(s, t):
freq[ord(a) - ord('a')] += 1
freq[ord(b) - ord('a')] -= 1
return all(f == 0 for f in freq) # O(n)
print(is_anagram_array('anagram', 'nagaram')) # True
print(is_anagram_array('rat', 'car')) # FalseLarik Frekuensi untuk Huruf Kecil
Ketika himpunan karakter terbatas (misalnya, hanya huruf kecil a-z), gantilah peta hash dengan larik frekuensi berukuran 26. Pengindeksan berdasarkan ord(c) - ord('a') memetakan 'a'→0, 'b'→1, ..., 'z'→25. Dalam praktiknya, larik lebih cepat daripada kamus karena lokalitas tembolok dan tidak adanya biaya pencincangan. Trik ini muncul dalam masalah anagram valid, permutasi anagram dalam teks, dan permutasi palindrom.
def build_freq(s):
freq = [0] * 26
for c in s:
freq[ord(c) - ord('a')] += 1
return freq
def is_anagram_fast(s, t):
return len(s) == len(t) and build_freq(s) == build_freq(t)
# Palindrome permutation: at most one odd-count character
def can_form_palindrome(s):
freq = build_freq(s)
odd_count = sum(1 for f in freq if f % 2 == 1)
return odd_count <= 1
print(can_form_palindrome('carerace')) # True ('racecar')
print(can_form_palindrome('hello')) # FalseMengelompokkan Anagram
Kelompokkan daftar teks sehingga semua anagram muncul bersama. Solusi kanonis O(n×m log m) menggunakan teks yang sudah diurutkan sebagai kunci peta hash. Semua anagram menghasilkan kunci terurut yang sama, sehingga masuk ke wadah yang sama. Variasi O(n×m) menggunakan tupel hitungan karakter sebagai kunci — lebih lambat saat menghitungnya, tetapi sama sekali tidak memerlukan pengurutan. Pendekatan berbasis kunci terurut hampir selalu lebih disukai karena lebih jelas.
from collections import defaultdict
def group_anagrams(strs):
groups = defaultdict(list)
for s in strs:
key = tuple(sorted(s)) # or ''.join(sorted(s))
groups[key].append(s)
return list(groups.values())
words = ['eat','tea','tan','ate','nat','bat']
result = group_anagrams(words)
for g in sorted(result, key=len, reverse=True):
print(sorted(g))
# ['ate', 'eat', 'tea']
# ['nat', 'tan']
# ['bat']Kunci Anagram dengan Tupel Hitungan
Untuk variasi pengelompokan anagram O(n×m), representasikan frekuensi setiap teks sebagai tupel berisi 26 hitungan: tuple(freq_array). Cara ini menghindari pengurutan, tetapi memerlukan pekerjaan O(26×n×m) untuk membangun semua kunci. Tupel dapat dicincang di Python, sehingga dapat digunakan sebagai kunci kamus. Variasi ini layak disebutkan ketika pewawancara meminta “solusi O(n×m) apa pun” — ini menunjukkan pemahaman tentang berbagai kompromi.
from collections import defaultdict
def group_anagrams_count(strs):
groups = defaultdict(list)
for s in strs:
freq = [0] * 26
for c in s:
freq[ord(c) - ord('a')] += 1
key = tuple(freq) # tuple is hashable
groups[key].append(s)
return list(groups.values())
print(group_anagrams_count(['eat','tea','tan','ate','nat','bat']))K Elemen dengan Frekuensi Tertinggi
Temukan k elemen yang paling sering muncul dalam sebuah larik. Penghitung + tumpukan-min: bangun peta frekuensi dalam O(n), lalu ambil k frekuensi terbesar menggunakan tumpukan-min berukuran k atau Counter.most_common(k). Pendekatan pengurutan berbasis wadah O(n) membuat wadah yang diindeks berdasarkan frekuensi (0 hingga n) dan mengumpulkan elemen dalam urutan frekuensi terbalik — elegan ketika k besar.
from collections import Counter
import heapq
def top_k_frequent_heap(nums, k):
freq = Counter(nums)
return heapq.nlargest(k, freq, key=freq.get)
def top_k_frequent_bucket(nums, k):
freq = Counter(nums)
buckets = [[] for _ in range(len(nums) + 1)]
for num, cnt in freq.items():
buckets[cnt].append(num)
result = []
for i in range(len(buckets)-1, -1, -1):
result.extend(buckets[i])
if len(result) >= k: break
return result[:k]
print(top_k_frequent_heap([1,1,1,2,2,3], 2)) # [1, 2]
print(top_k_frequent_bucket([1,1,1,2,2,3], 2)) # [1, 2]Peta Frekuensi untuk Permutasi dalam Teks
Tentukan apakah ada permutasi teks p yang muncul sebagai subteks dalam s. Peta frekuensi dari jendela sepanjang |p| harus sama dengan peta frekuensi p. Saat jendela bergeser, tambah hitungan karakter yang masuk dan kurangi hitungan karakter yang keluar. Membandingkan dua objek penghitung memerlukan O(26) setiap kali, sehingga totalnya O(n×26) = O(n). Lacak penghitung jumlah karakter yang terpenuhi untuk pemeriksaan kesamaan dalam O(1).
def check_inclusion_fast(p, s):
if len(p) > len(s): return False
need = [0] * 26
have = [0] * 26
for c in p:
need[ord(c)-ord('a')] += 1
for i in range(len(p)):
have[ord(s[i])-ord('a')] += 1
if need == have: return True
for i in range(len(p), len(s)):
have[ord(s[i])-ord('a')] += 1
have[ord(s[i-len(p)])-ord('a')] -= 1
if need == have: return True
return False
print(check_inclusion_fast('ab', 'eidbaooo')) # True
print(check_inclusion_fast('ab', 'eidboaoo')) # FalseJumlah Minimum Karakter untuk Membuat Anagram
Diberikan dua teks, temukan jumlah minimum penghapusan karakter agar salah satunya menjadi anagram dari yang lain. Hitung peta frekuensi untuk kedua teks; jawabannya adalah jumlah selisih mutlak frekuensi. Karakter yang ada dalam salah satu teks tetapi tidak ada dalam teks lainnya harus dihapus seluruhnya. Solusi O(n) ini menggunakan pola “menggabungkan dan menghitung selisih” pada peta frekuensi.
from collections import Counter
def min_steps_to_anagram(s, t):
freq_s = Counter(s)
freq_t = Counter(t)
steps = 0
# For each unique char across both strings:
all_chars = set(freq_s) | set(freq_t)
for c in all_chars:
steps += abs(freq_s.get(c, 0) - freq_t.get(c, 0))
return steps
# Or more concisely:
def min_steps_counter(s, t):
diff = Counter(s) - Counter(t)
return sum(diff.values())
print(min_steps_to_anagram('leetcode', 'practice')) # 5
print(min_steps_counter('leetcode', 'practice')) # 5Peta Frekuensi untuk Catatan Tebusan
Periksa apakah semua karakter dalam note dapat disediakan oleh karakter dalam magazine (setiap karakter majalah hanya dapat digunakan sekali). Bangun peta frekuensi karakter majalah; lalu untuk setiap karakter dalam catatan, kurangi hitungannya. Jika ada hitungan yang menjadi negatif, kembalikan False. Waktunya O(n + m) dan ruangnya O(1) untuk masukan yang dibatasi pada huruf kecil dengan menggunakan larik 26 elemen, bukan kamus.
def can_construct(note, magazine):
freq = [0] * 26
for c in magazine:
freq[ord(c) - ord('a')] += 1
for c in note:
freq[ord(c) - ord('a')] -= 1
if freq[ord(c) - ord('a')] < 0:
return False # insufficient supply
return True
print(can_construct('aa', 'aab')) # True
print(can_construct('aa', 'ab')) # False
print(can_construct('bg', 'efjbdfbdgbjjbghiklgdch')) # TruePencincangan Subteks Anagram Terpanjang
Untuk memeriksa apakah dua subteks dari teks yang sama merupakan anagram, gunakan hash polinomial dari frekuensi karakter yang bersifat komutatif (tidak bergantung pada urutan). XOR nilai karakter bersifat komutatif dan dapat diperbarui dalam O(1), tetapi memiliki kemungkinan tabrakan yang tinggi. Pendekatan yang lebih baik menggunakan pencincangan hasil kali bilangan prima (setiap karakter dipetakan ke bilangan prima yang berbeda; hasil kalinya tidak bergantung pada urutan). Ini adalah teknik khusus untuk wawancara tingkat lanjut.
# Prime product hash: each char maps to a prime
PRIMES = [2,3,5,7,11,13,17,19,23,29,31,37,41,
43,47,53,59,61,67,71,73,79,83,89,97,101]
def char_hash(s):
h = 1
for c in s:
h *= PRIMES[ord(c) - ord('a')]
return h
# Two windows with equal hash are likely anagrams
print(char_hash('listen')) # same as:
print(char_hash('silent')) # should matchDaftar Periksa Pola Peta Frekuensi
Kenali pola wawancara berbasis peta frekuensi berikut:
- Anagram valid: panjang sama + frekuensi sama → kesamaan penghitung atau perbandingan larik
- Mengelompokkan anagram: teks terurut atau tupel frekuensi sebagai kunci kamus
- k elemen paling sering: penghitung + tumpukan atau pengurutan berbasis wadah
- Permutasi dalam teks: jendela geser + perbandingan frekuensi
- Catatan tebusan: peta frekuensi persediaan, kurangi untuk permintaan
- Permutasi palindrom: paling banyak satu karakter dengan hitungan ganjil
from collections import Counter
# Palindrome permutation
def palindrome_permutation(s):
return sum(v % 2 for v in Counter(s).values()) <= 1
# First unique character
def first_unique(s):
freq = Counter(s)
for i, c in enumerate(s):
if freq[c] == 1:
return i
return -1
# Character replacement for longest repeat
def char_replacement(s, k):
freq = Counter()
left = best = max_freq = 0
for right, c in enumerate(s):
freq[c] += 1
max_freq = max(max_freq, freq[c])
if (right - left + 1) - max_freq > k:
freq[s[left]] -= 1
left += 1
best = max(best, right - left + 1)
return best
print(palindrome_permutation('carerace')) # True
print(first_unique('leetcode')) # 0
print(char_replacement('AABABBA', 1)) # 4Yang Berbeda: XOR untuk Frekuensi
XOR adalah alat yang ampuh untuk masalah frekuensi ketika tepat satu elemen memiliki frekuensi ganjil. XOR suatu angka dengan dirinya sendiri menghasilkan 0: a XOR a = 0. XOR semua elemen, ketika setiap nilai muncul sebanyak bilangan genap kecuali satu nilai, hanya menyisakan nilai yang frekuensinya ganjil. Cara ini memberikan waktu O(n) dan ruang O(1) — tidak memerlukan peta hash. Teknik ini dapat digeneralisasi untuk menemukan dua angka yang muncul dalam jumlah ganjil menggunakan sifat-sifat XOR.
def single_number(nums):
result = 0
for n in nums:
result ^= n # XOR cancels pairs
return result
print(single_number([4,1,2,1,2])) # 4
print(single_number([2,2,1])) # 1
# Find the unique character in an anagram check:
def find_difference(s, t):
result = 0
for c in s + t:
result ^= ord(c)
return chr(result)
print(find_difference('abcd', 'abcde')) # 'e'Uji Singkat
Ujilah pemahaman Anda tentang konsep Struktur Data & Algoritma — Persiapan Wawancara Pemrograman dari pelajaran ini.
Rangkuman Pelajaran
Dalam pelajaran ini Anda mempelajari: peta frekuensi karakter adalah alat utama untuk mendeteksi anagram — gunakan larik 26 elemen untuk alfabet terbatas atau penghitung untuk karakter sembarang, kunci kamus berupa teks terurut atau tupel frekuensi mengelompokkan semua anagram dalam waktu O(n × m log m) atau O(n × m), dan XOR menghapus pasangan dengan rapi untuk masalah hitungan ganjil satu elemen, sehingga memberikan waktu O(n) dengan ruang O(1) ketika kamus tidak diperlukan. Selanjutnya kita akan mempelajari pengodean teks, pembalikan, dan teknik palindrom.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Anagram dan Peta Frekuensi Karakter” gratis?
Ya — teks lengkap “Anagram dan Peta Frekuensi Karakter” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Coding Interview Prep, upgrade ke CoddyKit PRO. Kursus Coding Interview Prep mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Anagram dan Peta Frekuensi Karakter”?
Selesaikan group-anagrams, valid-anagram, dan permutation-in-string menggunakan array frekuensi serta hash map untuk solusi O(n). Kamu berlatih Coding Interview Prep dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Coding Interview Prep?
Tidak diperlukan pengalaman sebelumnya. Coding Interview Prep di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Anagram dan Peta Frekuensi Karakter” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Coding Interview Prep ini?
Ya. Setiap pelajaran Coding Interview Prep menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- API String Python untuk Wawancara
- Sliding Window untuk Substring
- Anagram dan Peta Frekuensi Karakter
- Pengodean String, Pembalikan, dan Palindrome