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

Two-Pointer & Sliding Window

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

สองเทคนิคที่เปลี่ยนโจทย์ array/string จาก O(n²) เป็น O(n) — เจอบ่อยที่สุดในการสัมภาษณ์

two-pointer และ sliding window เป็นเทคนิคที่ใช้ "ตัวชี้" เดินบน array/string อย่างชาญฉลาด แทนการวน loop ซ้อน ทำให้แก้โจทย์ได้เร็วขึ้นมาก — เป็นแพตเทิร์นที่เจอบ่อยสุดในโจทย์สัมภาษณ์

Two-Pointer: สองหัวเข้าหากัน

ใช้ตัวชี้สองตัวที่ปลายทั้งสองข้าง ขยับเข้าหากันตามเงื่อนไข เช่น ตรวจ palindrome หรือหาคู่ผลรวมใน array ที่เรียงแล้ว

python
# ตรวจ palindrome
def is_palindrome(s):
    left, right = 0, len(s) - 1
    while left < right:
        if s[left] != s[right]:
            return False
        left += 1
        right -= 1
    return True

print(is_palindrome("racecar"))   # True

# two-sum บน array ที่เรียงแล้ว (O(n))
def two_sum_sorted(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo < hi:
        s = arr[lo] + arr[hi]
        if s == target:
            return (lo, hi)
        elif s < target:
            lo += 1        # ผลรวมน้อยไป ขยับซ้าย
        else:
            hi -= 1        # ผลรวมมากไป ขยับขวา
    return None

Sliding Window: หน้าต่างเลื่อน

ใช้กับโจทย์ "ช่วงต่อเนื่อง" (subarray/substring) — เลื่อนหน้าต่างไปบน array โดยไม่คำนวณซ้ำ

python
# ผลรวมสูงสุดของ subarray ยาว k (fixed window)
def max_sum_window(arr, k):
    window = sum(arr[:k])
    best = window
    for i in range(k, len(arr)):
        window += arr[i] - arr[i - k]   # เพิ่มตัวใหม่ ลบตัวเก่า
        best = max(best, window)
    return best

print(max_sum_window([1, 4, 2, 10, 2, 3], 3))   # 16 (2+10+... )
python
# substring ยาวสุดที่ไม่มีตัวซ้ำ (variable window)
def longest_unique(s):
    seen = set()
    left = best = 0
    for right in range(len(s)):
        while s[right] in seen:      # หดหน้าต่างจากซ้ายจนไม่ซ้ำ
            seen.remove(s[left])
            left += 1
        seen.add(s[right])
        best = max(best, right - left + 1)
    return best

print(longest_unique("abcabcbb"))   # 3 ('abc')
เห็น 'ช่วงต่อเนื่อง' → คิดถึง sliding window

โจทย์ที่พูดถึง subarray/substring ต่อเนื่อง, ผลรวม/นับในช่วง → มักแก้ด้วย sliding window ได้ O(n) แทน brute force O(n²) ส่วนโจทย์ array เรียงแล้ว/หาคู่ → คิดถึง two-pointer

สรุปหัวข้อนี้

  • two-pointer: ตัวชี้สองตัวเดินตามเงื่อนไข — palindrome, two-sum (เรียงแล้ว)
  • sliding window: หน้าต่างเลื่อนบนช่วงต่อเนื่อง ไม่คำนวณซ้ำ
  • fixed window (ขนาดคงที่) vs variable window (หด/ขยายตามเงื่อนไข)
  • เปลี่ยน O(n²) → O(n); เห็น subarray/substring ต่อเนื่อง → sliding window
แบบฝึกหัด

1) ตรวจ palindrome ด้วย two-pointer 2) two-sum บน array เรียงแล้ว 3) หาผลรวมสูงสุดของ window ยาว k 4) substring ยาวสุดที่ไม่มีตัวซ้ำ