หมี นาก และนกฮูกยืนหน้าแถวกล่องตัวเลข มีกรอบหน้าต่างเลื่อนสีมิ้นต์

LeetCode #239 Sliding Window Maximum: คิวสองหัวชนะการหา max ทุกหน้าต่าง

น้องกายEngineering

โจทย์ Sliding Window Maximum #239 ให้ลิสต์ตัวเลขกับขนาดหน้าต่าง k แล้วขอค่ามากสุดของทุกช่วงต่อเนื่องยาว k

ตัวละคร: หมีขี้เกียจ (max ทีละหน้าต่าง), นากคิว (deque เก็บดัชนีลดลง), บารอน กรรมการ

วิธีหมี — O(n·k)

ทุกจุดเริ่มเรียก max บนช่วง เขียนง่าย ไวท์บอร์ดโอเค แต่ช้าเมื่อ n และ k ใหญ่

วิธีนาก — O(n) ด้วย deque

เก็บดัชนีในคิวสองหัวให้ค่าลดลงจากหัวคิว ไล่ขวาทีละช่อง เอาของหมดอายุและของที่เล็กกว่าออก หัวคิวคือคำตอบของหน้าต่างนั้น (collections.deque)

ตารางเลือก

สถานการณ์เลือก
สัมภาษณ์อธิบาย deque
n เล็กmax ตรงๆ ก็ได้
hot pathdeque O(n)

Benchmark (เครื่องนี้ 2026-10-14)

n=20,000, k=50

วิธีเวลา
deque3.05 ms
naive max15.48 ms

โค้ด

from collections import deque

def max_sliding_window(nums, k):
    dq = deque()
    out = []
    for i, x in enumerate(nums):
        while dq and dq[0] <= i - k:
            dq.popleft()
        while dq and nums[dq[-1]] <= x:
            dq.pop()
        dq.append(i)
        if i >= k - 1:
            out.append(nums[dq[0]])
    return out

assert max_sliding_window([1,3,-1,-3,5,3,6,7], 3) == [3,3,5,5,6,7]
print("ok")

บารอนสรุป

บนอินพุตยาว deque ชนะชัด หมีเหมาะสอนก่อน แล้วค่อยย้ายไปคิว

Recap

  • ขอ max ทุกหน้าต่างขนาด k
  • naive O(n·k) vs deque O(n)
  • Benchmark: 3.05 ms vs 15.48 ms ที่ n=20k k=50