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

Intervals — พื้นฐาน & แนวคิด

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

sort (เรียง) interval ก่อน แล้วใช้ greedy เทียบ interval ติดกัน เพื่อจัดการปัญหาช่วงที่ทับซ้อน

Intervals (ช่วง) คือกลุ่มโจทย์ที่ข้อมูลแต่ละชิ้นเป็น interval (ช่วง) มี start (จุดเริ่ม) กับ end (จุดจบ) เช่น [1,3] หมายถึงช่วงตั้งแต่ 1 ถึง 3 โจทย์มักถามเรื่อง overlap (การทับซ้อน) ของ interval เช่น ต้องลบ interval ไหนออกบ้างให้ไม่ทับกัน หรือ merge (รวม) interval ที่ซ้อนกันเข้าด้วยกัน กุญแจสำคัญเกือบทุกข้อคือ sort ก่อน แล้วค่อย iterate (วน) เทียบทีละคู่

นิยามของคำว่า ทับกัน

สอง interval [a1, b1] กับ [a2, b2] จะ overlap เมื่อ interval หนึ่งเริ่มก่อนที่อีก interval จะจบ พูดง่าย ๆ คือถ้า sort ให้ interval แรกมาก่อน interval ที่สองจะทับก็ต่อเมื่อ start ของ interval ที่สองน้อยกว่า end ของ interval แรก เช่น [1,3] กับ [2,4] overlap กัน (เพราะ 2 < 3) แต่ [1,2] กับ [2,4] มักถือว่าไม่ทับ (แค่ปลายชนกันที่ 2 แต่ไม่ซ้อนกัน)

sort แล้ว greedy

เทคนิคหลักคือ sort interval ทั้งหมดก่อน จะ sort ตาม start หรือ end ขึ้นกับโจทย์ จากนั้น iterate ทีละ interval แบบ greedy คือตัดสินใจโดยดูแค่ interval ล่าสุดที่เก็บไว้เทียบกับ interval ปัจจุบัน ไม่ต้องมองย้อนกลับไปไกล

python
# โครงทั่วไปของโจทย์ intervals
intervals = [[1, 3], [2, 4], [3, 5]]

# sort ตามจุดจบ (บางโจทย์ sort ตามจุดเริ่ม)
intervals.sort(key=lambda x: x[1])

prev_end = float("-inf")   # จุดจบของช่วงล่าสุดที่เลือกไว้
for start, end in intervals:
    if start >= prev_end:
        # ไม่ทับกับช่วงก่อนหน้า เลือกช่วงนี้ได้
        prev_end = end
    else:
        # ทับกัน ต้องตัดสินใจ (ข้าม/ลบ ช่วงนี้ ฯลฯ)
        pass

ทำไม sort ถึงช่วย เพราะเมื่อ sort ตาม end แล้ว การเลือก interval ที่จบเร็วที่สุดก่อนเสมอ จะเหลือที่ว่างให้ interval ถัด ๆ ไปมากที่สุด นี่คือหลักการ greedy คลาสสิกที่พิสูจน์ได้ว่าให้คำตอบที่ดีที่สุด

sort ตาม start หรือ end

ถ้าโจทย์ให้เลือก interval ให้ได้มากที่สุดโดยไม่ทับกัน (activity selection) นิยม sort ตาม end แต่ถ้าโจทย์ให้ merge interval ที่ซ้อนกัน นิยม sort ตาม start ลองคิดว่าตัวไหนทำให้ greedy ตัดสินใจได้ง่ายกว่า

พร้อมลุยยัง

หมวดนี้มี 2 ข้อ (LC435, LC452) กดถัดไปเริ่มข้อแรกได้เลย