- vừa được xem lúc

Tìm hiểu thuật toán Sliding Window

0 0 2

Người đăng: Cường Nguyễn

Theo Viblo Asia

Sliding Window (cửa sổ trượt) là một kỹ thuật thường được sử dụng để xử lý các dãy liên tiếp trong mảng hoặc chuỗi một cách hiệu quả, bằng cách duy trì một "cửa sổ" chứa một phần tử liên tục của dữ liệu và di chuyển nó qua toàn bộ dãy. Kỹ thuật này giúp biến các giải pháp lồng nhau với độ phức tạp O(n²) thành một vòng lặp đơn với độ phức tạp O(n). Nó đặc biệt hữu ích với các bài toán yêu cầu tìm kiếm dãy con (subarray hoặc substring) thỏa mãn một điều kiện nào đó trong chuỗi hoặc mảng.

Sliding Window Hoạt Động Như Thế Nào?

Có hai dạng phổ biến của thuật toán Sliding Window:

1. Cửa Sổ Có Kích Thước Cố Định (Fixed-Size)

Dạng này được dùng khi kích thước cửa sổ k đã được cho trước, ví dụ: “tìm tổng lớn nhất của một đoạn con gồm k phần tử liên tiếp”. Cách tiếp cận như sau:

Khởi tạo: Tính tổng của k phần tử đầu tiên.

Trượt cửa sổ: Ở mỗi bước, loại bỏ phần tử đầu tiên khỏi tổng, thêm phần tử mới vào cửa sổ.

Cập nhật kết quả: So sánh và lưu lại tổng lớn nhất (hoặc nhỏ nhất).

Tiếp tục: Lặp lại cho đến hết mảng.

Ví dụ: Với arr = [5, 2, -1, 0, 3], k = 3, tổng đầu tiên là 6. Trượt sang phải, tổng tiếp theo là 1, rồi 2. Tổng lớn nhất là 6.

2. Cửa Sổ Có Kích Thước Linh Hoạt (Variable-Size)

Dùng khi độ dài của đoạn con không cố định, nhưng phụ thuộc vào điều kiện (ví dụ: tổng ≥ S, không quá K ký tự khác nhau,...). Các bước như sau:

Mở rộng cửa sổ: Dùng hai con trỏ (left, right) để mở rộng cửa sổ về bên phải cho đến khi thỏa điều kiện.

Thu hẹp từ bên trái: Khi điều kiện bị vi phạm, thu hẹp cửa sổ bằng cách di chuyển con trỏ trái sang phải.

Ghi nhận kết quả: Lưu kết quả mỗi khi điều kiện thỏa mãn.

Tiếp tục: Di chuyển con trỏ phải cho đến hết chuỗi hoặc mảng.

Đây là kỹ thuật hai con trỏ, trong đó mỗi phần tử chỉ bị duyệt tối đa 2 lần, giúp đạt hiệu suất O(n).

Bài Toán Mẫu: Tổng Lớn Nhất Của Đoạn Con Kích Thước K#

Đề bài: Cho một mảng các số nguyên và số k, tìm tổng lớn nhất của bất kỳ đoạn con liên tiếp nào có độ dài k.

Giải pháp Sliding Window bằng Python:

def max_subarray_sum_k(arr, k): n = len(arr) if n < k: raise ValueError("k lớn hơn độ dài mảng") window_sum = sum(arr[:k]) max_sum = window_sum for i in range(k, n): window_sum += arr[i] - arr[i - k] max_sum = max(max_sum, window_sum) return max_sum

Ví dụ:

print(max_subarray_sum_k([100, 200, 300, 400], 2)) # Kết quả: 700

Thay vì tính tổng từ đầu mỗi lần, ta chỉ cập nhật tổng bằng cách trừ đi phần tử cũ và cộng phần tử mới — giúp giảm độ phức tạp từ O(n*k) xuống O(n).

Khi Nào Nên Dùng Sliding Window?

Hãy cân nhắc sử dụng Sliding Window khi:

  • Bài toán yêu cầu xử lý đoạn liên tiếp (subarray, substring).
  • Cần tìm giá trị tối ưu (tối đa, tối thiểu, thỏa điều kiện) trong một dãy con liên tiếp.
  • Câu hỏi nhắc đến kích thước k cố định → dùng cửa sổ cố định.
  • Câu hỏi nhắc đến điều kiện linh hoạt → dùng cửa sổ biến đổi.
  • Bài toán duyệt nhiều đoạn con có phần trùng lặp → sliding window giúp tiết kiệm thời gian.
  • Dữ liệu đến theo luồng (streaming data) hoặc cần xử lý theo thời gian thực.
  • Các Bài Tập Kinh Điển Để Luyện Tập Sliding Window
  • Dưới đây là một số bài toán điển hình nên luyện tập:
  • Tổng lớn nhất đoạn con độ dài K (như bài mẫu ở trên).
  • Chuỗi con dài nhất có K ký tự khác nhau.
  • Đếm chuỗi con là hoán vị (anagram) của một chuỗi cho trước.
  • Chuỗi con nhỏ nhất có chứa tất cả ký tự của chuỗi T.
  • Đếm đoạn con có tổng ≥ S (hoặc ≤ S).
  • Chuỗi dài nhất chứa nhiều nhất K lần thay đổi ký tự.
  • "Fruit Into Baskets": tối đa 2 loại ký tự trong một chuỗi con.
  • Dãy con sản phẩm < K.
  • Tối đa số 1 liên tiếp sau khi đổi tối đa 1 số 0.
  • Sliding Window Maximum: tìm giá trị lớn nhất trong mỗi cửa sổ trượt.

Những bài toán này đều xuất hiện thường xuyên trong các buổi phỏng vấn coding và là cách tốt để rèn luyện khả năng nhận biết và áp dụng Sliding Window.

Kết Luận

Sliding Window là một công cụ mạnh mẽ, giúp giải quyết hiệu quả các bài toán liên quan đến chuỗi hoặc mảng liên tiếp. Khi được áp dụng đúng, nó giúp giảm đáng kể độ phức tạp và tối ưu hiệu năng. Là một lập trình viên chuẩn bị cho phỏng vấn kỹ thuật, bạn nên thành thạo kỹ thuật này. Hãy luyện tập nhiều bài toán đa dạng để rèn kỹ năng nhận diện bài toán phù hợp và triển khai sliding window một cách trơn tru.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Thuật toán quay lui (Backtracking)

Quay lui là một kĩ thuật thiết kế giải thuật dựa trên đệ quy. Ý tưởng của quay lui là tìm lời giải từng bước, mỗi bước chọn một trong số các lựa chọn khả dĩ và đệ quy.

0 0 60

- vừa được xem lúc

Các thuật toán cơ bản trong AI - Phân biệt Best First Search và Uniform Cost Search (UCS)

Nếu bạn từng đọc các thuật toán trong AI (Artificial Intelligence - Trí tuệ nhân tạo), rất có thể bạn từng nghe qua về các thuật toán tìm kiếm cơ bản: UCS (thuộc chiến lược tìm kiếm mù) và Best First Search (thuộc chiến lược tìm kiếm kinh nghiệm). Khác nhau rõ từ khâu phân loại rồi, thế nhưng hai th

0 0 184

- vừa được xem lúc

Sử dụng vector trong lập trình C++ - giải bài toán lập trình muôn thủa

Chào buổi tối mọi người, hôm nay lang thang trên mạng bắt gặp bài toán quen thuộc một thời của quãng đường sinh viên IT. Đấy chính là câu số 1 trong đề thi dưới đây:.

0 0 69

- vừa được xem lúc

MÔ PHỎNG THUẬT TOÁN VƯƠNG HẠO TRONG PROLOG

. 1. Các luật suy diễn trong thuật toán Vương Hạo. Luật 1: Chuyển vế các giả thuyết và kết luận ở dạng phủ định. Ví dụ: p v q, !(r ^ s), !q, p v r -> s, !p <=> p v q, p v r, p -> s, r ^ s, q.

0 0 102

- vừa được xem lúc

A* Search Algorithm

What is A* Search Algorithm. How it works. . Explanation.

0 0 64

- vừa được xem lúc

Python: Jump Search

Search là một từ khóa khá là quen thuộc đối với chúng ta. Hiểu theo đúng nghĩa đen của nó chính là "Tìm kiếm".

0 0 61