Trong nhiều năm dạy lập trình cho học sinh, tôi nhận ra một nghịch lý rất phổ biến: rất nhiều học sinh thuộc làu C++ hoặc Python, code thành thạo, nhưng không giải quyết được bài toán khi vào contest hay khi bị thay đổi ngữ cảnh.
Vì sao lại như vậy? Bởi vì họ đang học ngôn ngữ chơi, chưa học giải thuật.
Học lập trình không đồng nghĩa với học tư duy thuật toán
Việc biết sử dụng vector
, map
, for
, if
… giống như việc biết cách dùng bút để viết. Nó là công cụ, không phải tư duy.
Tư duy thuật toán đòi hỏi học sinh:
- Hiểu được vấn đề cốt lõi là gì
- Biết chia nhỏ vấn đề
- Biết chọn mô hình tư duy phù hợp (greedy, quy hoạch động, DFS, map…)
- Biết tìm quy luật, tính chất, khai thác cấu trúc dữ liệu
Không có bất kỳ ngôn ngữ nào giúp học sinh tự nên tư duy được, trừ khi cách dạy giúp họ xây lại mối liên hệ giữa code và logic.
Phương pháp dạy đáng tin cậy: Từ đề ý đến giải pháp rồi mới đến code
Khi gặp một bài toán, thay vì đọc xong rồi code ngay, hãy hướng dẫn học sinh làm theo trình tự:
- Phân tích bài toán: Input gì, Output gì, ràng buộc nào?
- Tìm quy luật ẩn: Bài toán có tính chất đệ quy, định hướng greedy hay tìm kiếm nhị phân?
- Chọn cấu trúc dữ liệu: Nên dùng mảng, map, set hay segment tree?
- Thiết kế giải thuật: Viết lược thuật toán trước khi viết code
- Triển khai code và test
Minh họa: Bài toán kinh điển “Two Sum”
Đề bài: Cho một mảng số nguyên nums
và một giá trị target
. Hãy tìm 2 phần tử trong mảng sao cho tổng bằng target
. Trả về chỉ số của 2 phần tử đó.
Cách 1: Brute force
- Duyệt 2 vòng for lồng nhau
- Kiểm tra từng cặp
i, j
xemnums[i] + nums[j] == target
- Tốt để bắt đầu, giúp hiểu logic cơ bản
- Nhưng: Tốn O(n^2)
Cách 2: Dùng map (hash)
- Duyệt mỗi phần tử
x
, tìmtarget - x
trong map - Lưu giá trị và vị trí đã duyệt vào map
- Giảm thời gian xuống O(n)
- Yêu cầu học sinh hiểu cách map hoạt động
Cách 3: Tư duy hệ thống
- Câu hỏi gợi mở: Liệu có thể tái sử dụng giá trị đã duyệt?
- Nhận diện pattern: Bài này thuộc dạng “truy vấn phần tử bổ sung” → Hash map
- Tư duy trên cả lớp bài toán khác: 3 sum, 4 sum, two product…
Kết luận
Khi học sinh được hướng dẫn khám phá bài toán trước khi code, không những học tốt hơn mà còn nhớ lâu, hiểu rõ, áp dụng được cho những dạng khác.
Người dạy lập trình thời AI không còn là người giỏi code nhất, mà là người giúp học sinh nhìn ra cái lõi tư duy trong bài toán. Có như vậy, code mới thật sự “có ý nghĩa”.