Two-Pointer & Sliding Window
สองเทคนิคที่เปลี่ยนโจทย์ array/string จาก O(n²) เป็น O(n) — เจอบ่อยที่สุดในการสัมภาษณ์
two-pointer และ sliding window เป็นเทคนิคที่ใช้ "ตัวชี้" เดินบน array/string อย่างชาญฉลาด แทนการวน loop ซ้อน ทำให้แก้โจทย์ได้เร็วขึ้นมาก — เป็นแพตเทิร์นที่เจอบ่อยสุดในโจทย์สัมภาษณ์
Two-Pointer: สองหัวเข้าหากัน
ใช้ตัวชี้สองตัวที่ปลายทั้งสองข้าง ขยับเข้าหากันตามเงื่อนไข เช่น ตรวจ palindrome หรือหาคู่ผลรวมใน array ที่เรียงแล้ว
# ตรวจ 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 NoneSliding Window: หน้าต่างเลื่อน
ใช้กับโจทย์ "ช่วงต่อเนื่อง" (subarray/substring) — เลื่อนหน้าต่างไปบน array โดยไม่คำนวณซ้ำ
# ผลรวมสูงสุดของ 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+... )# 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')โจทย์ที่พูดถึง 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 ยาวสุดที่ไม่มีตัวซ้ำ