On this page
โจทย์ Dictionary & Set
นับความถี่ จับคู่ ตัดซ้ำ และค้นหาเร็ว — dict/set คือเครื่องมือที่เปลี่ยนโจทย์ช้าให้เร็ว
Dictionary และ Set เป็นกุญแจของโจทย์ประเภท "นับ", "จับคู่", และ "เคยเห็นไหม" เพราะค้นหาเร็ว O(1) โจทย์ชุดนี้ฝึกใช้สองโครงสร้างนี้แก้ปัญหาอย่างมีประสิทธิภาพ
ข้อ 1 — นับความถี่คำ 🟢
รับประโยค แล้วนับว่าคำแต่ละคำปรากฏกี่ครั้ง เช่น "the cat the dog" → the:2, cat:1, dog:1
เฉลย + คำอธิบาย
s = "the cat the dog the bird"
count = {}
for word in s.split():
count[word] = count.get(word, 0) + 1
print(count) # {'the': 3, 'cat': 1, 'dog': 1, 'bird': 1}
# หรือใช้ Counter สำเร็จรูป
from collections import Counter
print(Counter(s.split()))split() ตัดประโยคเป็นลิสต์คำ แล้วนับด้วย pattern count[x] = count.get(x, 0) + 1 — เหมือนนับตัวอักษรแต่เปลี่ยนเป็นนับคำ Counter ทำให้สั้นลงในงานจริง
ข้อ 2 — หาค่าที่ปรากฏบ่อยสุด 🟡
รับลิสต์ แล้วหาว่าค่าไหนปรากฏบ่อยที่สุด เช่น [1,3,3,2,3,1] → 3
เฉลย + คำอธิบาย
def most_common(nums):
count = {}
for n in nums:
count[n] = count.get(n, 0) + 1
# หา key ที่ value มากสุด
return max(count, key=count.get)
print(most_common([1, 3, 3, 2, 3, 1])) # 3นับความถี่ลง dict ก่อน แล้วใช้ max(count, key=count.get) — บอก max ว่า "เทียบ key แต่ละตัวด้วยค่าของมัน (count.get)" จึงได้ key ที่มีความถี่สูงสุด เป็นเทคนิคใช้ max/min กับ dict ที่มีประโยชน์มาก
ข้อ 3 — สมาชิกร่วมของสองลิสต์ 🟢
หาค่าที่อยู่ในทั้งสองลิสต์ เช่น [1,2,3,4] กับ [3,4,5,6] → {3, 4}
เฉลย + คำอธิบาย
a = [1, 2, 3, 4]
b = [3, 4, 5, 6]
common = set(a) & set(b) # intersection
print(common) # {3, 4}
only_in_a = set(a) - set(b) # อยู่ใน a ไม่อยู่ใน b
print(only_in_a) # {1, 2}แปลงเป็น set แล้วใช้ตัวดำเนินการเซ็ต: & (ร่วม), | (รวม), - (ต่าง) สั้นและเร็วกว่าการวน loop ซ้อนเทียบทุกคู่ (O(n²)) มาก — set ทำให้เหลือ O(n)
ข้อ 4 — มีค่าซ้ำไหม 🟢
เช็คว่าในลิสต์มีค่าซ้ำกันไหม คืน True/False เช่น [1,2,3,2] → True, [1,2,3] → False
เฉลย + คำอธิบาย
def has_duplicate(nums):
return len(set(nums)) != len(nums)
print(has_duplicate([1, 2, 3, 2])) # True
print(has_duplicate([1, 2, 3])) # Falseเคล็ดลับสั้น ๆ: set ตัดค่าซ้ำออก ถ้าจำนวนสมาชิกใน set น้อยกว่าในลิสต์เดิม แปลว่ามีตัวซ้ำ วิธีนี้ O(n) เทียบกับการวนเทียบทุกคู่ O(n²)
ข้อ 5 — จัดกลุ่ม anagram 🔴
จัดกลุ่มคำที่เป็น anagram กัน เช่น ["eat","tea","tan","ate","nat"] → [["eat","tea","ate"], ["tan","nat"]]
คำที่เป็น anagram กันจะได้ "กุญแจ" เดียวกันเมื่อเรียงตัวอักษร เช่น eat/tea/ate ต่างเรียงได้ "aet" ใช้กุญแจนี้เป็น key ของ dict ที่เก็บลิสต์ของคำ
เฉลย + คำอธิบาย
def group_anagrams(words):
groups = {}
for word in words:
key = "".join(sorted(word)) # เรียงตัวอักษรเป็นกุญแจ
if key not in groups:
groups[key] = []
groups[key].append(word)
return list(groups.values())
print(group_anagrams(["eat","tea","tan","ate","nat"]))
# [['eat','tea','ate'], ['tan','nat']]ต่อยอดจากโจทย์ anagram เดิม: sorted(word) ให้ลายเซ็นเดียวกันสำหรับ anagram กลุ่มเดียวกัน ใช้มันเป็น key ของ dict ที่ map ลายเซ็น → ลิสต์คำ วน 1 รอบจัดกลุ่มได้เลย O(n) — เห็นไหมว่า dict ทรงพลังแค่ไหน
สังเกตว่าโจทย์เกือบทุกข้อใช้ pattern เดียวกัน: นับ/จัดกลุ่มด้วย dict หรือเช็คสมาชิก/ตัดซ้ำด้วย set เมื่อเจอคำว่า "นับ", "จับคู่", "ซ้ำ", "เคยเห็น" ให้นึกถึง dict/set ทันที