Notes & software courses · Free to learn
Aph's Blog
On this page

โจทย์ Dictionary & Set

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

นับความถี่ จับคู่ ตัดซ้ำ และค้นหาเร็ว — dict/set คือเครื่องมือที่เปลี่ยนโจทย์ช้าให้เร็ว

Dictionary และ Set เป็นกุญแจของโจทย์ประเภท "นับ", "จับคู่", และ "เคยเห็นไหม" เพราะค้นหาเร็ว O(1) โจทย์ชุดนี้ฝึกใช้สองโครงสร้างนี้แก้ปัญหาอย่างมีประสิทธิภาพ

ข้อ 1 — นับความถี่คำ 🟢

รับประโยค แล้วนับว่าคำแต่ละคำปรากฏกี่ครั้ง เช่น "the cat the dog" → the:2, cat:1, dog:1

เฉลย + คำอธิบาย
python
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

เฉลย + คำอธิบาย
python
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}

เฉลย + คำอธิบาย
python
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

เฉลย + คำอธิบาย
python
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 ที่เก็บลิสต์ของคำ

เฉลย + คำอธิบาย
python
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 ทันที