Ứng dụng của Stack:
Thao tác Undo / Redo trong các phần mềm soạn thảo văn bản (lưu lại lịch sử thay đổi).
Lịch sử duyệt web (Back / Forward nút trên browser).
Quản lý Call Stack trong hệ điều hành & ngôn ngữ lập trình khi gọi hàm đệ quy.
Trình biên dịch: Kiểm tra tính hợp lệ của dấu ngoặc đóng/mở trong cú pháp code.
Ứng dụng của Queue:
Quản lý tiến trình trong Hệ điều hành (CPU Task Scheduling).
Bộ đệm dữ liệu (Buffer) trong truyền dữ liệu mạng hoặc streaming video.
Thuật toán duyệt đồ thị theo chiều rộng (BFS - Breadth First Search).
Cho một chuỗi chỉ chứa các ký tự ngoặc (), {}, []. Hãy kiểm tra chuỗi đó có hợp lệ hay không.
Một chuỗi ngoặc hợp lệ khi:
Ngoặc mở phải được đóng bởi ngoặc cùng loại.
Ngoặc mở phải được đóng theo đúng thứ tự.
Ví dụ:
"({[]})" $\rightarrow$ Hợp lệ (True)
"([)]" $\rightarrow$ Không hợp lệ (False) (ngoặc ] bị đóng sai vị trí)
Duyệt từng ký tự trong chuỗi:
Nếu là ngoặc mở (, {, [ $\rightarrow$ Push vào Stack.
Nếu là ngoặc đóng ), }, ] $\rightarrow$ Pop phần tử đỉnh Stack ra so sánh. Nếu không khớp loại hoặc Stack đang rỗng $\rightarrow$ Trả về False.
Kết thúc chuỗi, nếu Stack rỗng $\rightarrow$ Trả về True.
def is_valid_parentheses(s: str) -> bool:
stack = []
# Ánh xạ ngoặc đóng -> ngoặc mở tương ứng
mapping = {")": "(", "}": "{", "]": "["}
for char in s:
if char in mapping:
# Lấy phần tử đỉnh stack nếu stack không rỗng
top_element = stack.pop() if stack else "#"
if mapping[char] != top_element:
return False
else:
# Nếu là ngoặc mở, đẩy vào stack
stack.append(char)
# Nếu stack rỗng tức là tất cả ngoặc mở đều đã được đóng hợp lệ
return len(stack) == 0
# Kiểm thử
print(is_valid_parentheses("({[]})")) # Output: True
print(is_valid_parentheses("([)]")) # Output: False
Độ phức tạp thời gian: $O(N)$ (duyệt qua chuỗi đúng 1 lần).
Độ phức tạp bộ nhớ: $O(N)$ (trường hợp xấu nhất Stack lưu toàn bộ $N$ ngoặc mở).
Hệ thống xử lý đơn hàng tự động của một trang thương mại điện tử tiếp nhận hàng nghìn đơn mua từ khách hàng cùng lúc. Hệ thống cần đảm bảo đơn nào gửi trước sẽ được xử lý đóng gói và giao trước.
Cấu trúc dữ liệu nào (Stack hay Queue) là lựa chọn chính xác cho tính năng này? Vì sao?
Nếu bổ sung thêm tính năng: "Cho phép người dùng hoàn tác (Cancel) thao tác đặt hàng vừa bấm trong vòng 5 giây", thao tác hoàn tác này nên được lưu trữ bằng cấu trúc dữ liệu nào?
Dựa vào nguyên lý LIFO của Stack, hãy viết một hàm Python reverse_string(text: str) -> str nhận vào một chuỗi ký tự và trả về chuỗi đó theo chiều ngược lại.
Ví dụ: reverse_string("DSA") $\rightarrow$ "ASD"
(Yêu cầu: Cài đặt bằng cách push từng ký tự vào Stack, sau đó pop ra để ghép thành chuỗi mới).