Explore all courses in this category.
Explore all courses in this category.
Nguyễn Đình Cường
0 comment
09 Nov, 2026
Gần như mọi bài thuật toán đều kết thúc bằng câu hỏi: "Độ phức tạp thời gian và bộ nhớ của lời giải này là gì?". Big O không đáng sợ nếu bạn nắm vài quy tắc và nhận ra các mẫu quen thuộc. Bài này giúp bạn ước lượng nhanh và giải thích rõ ràng.
Big O mô tả cách chi phí (thời gian hoặc bộ nhớ) tăng theo kích thước đầu vào n khi n lớn, thường xét trường hợp xấu nhất. Nó bỏ qua hằng số và các số hạng nhỏ: 3n + 10 vẫn là O(n), còn n² + n là O(n²). Đây là công cụ so sánh xu hướng, không phải thời gian chạy chính xác.
| Ký hiệu | Tên | Ví dụ |
|---|---|---|
| O(1) | Hằng số | Truy cập phần tử mảng theo chỉ số |
| O(log n) | Logarit | Tìm kiếm nhị phân |
| O(n) | Tuyến tính | Duyệt qua mảng một lần |
| O(n log n) | Tuyến tính logarit | Sắp xếp hiệu quả như merge sort |
| O(n²) | Bình phương | Hai vòng lặp lồng nhau |
| O(2^n) | Hàm mũ | Sinh mọi tập con |
// Cách 1: hai vòng lặp, O(n^2) thời gian, O(1) bộ nhớfunction twoSumBrute(nums, target) { for (let i = 0; i < nums.length; i++) { for (let j = i + 1; j < nums.length; j++) { if (nums[i] + nums[j] === target) return [i, j]; } } return null;}// Cách 2: hash map, O(n) thời gian, O(n) bộ nhớfunction twoSum(nums, target) { const seen = new Map(); for (let i = 0; i < nums.length; i++) { const need = target - nums[i]; if (seen.has(need)) return [seen.get(need), i]; seen.set(nums[i], i); } return null;}Cách thứ hai đánh đổi bộ nhớ lấy tốc độ. Khi trình bày, hãy nói rõ sự đánh đổi này; đó là điều người phỏng vấn muốn nghe.
Đừng quên không gian phụ ngoài đầu vào. Tạo một mảng mới kích thước n là O(n) bộ nhớ. Đệ quy sâu d tầng tốn O(d) cho ngăn xếp gọi hàm, nên đệ quy trên danh sách dài có thể gây tràn ngăn xếp. Giải bằng vòng lặp thường tiết kiệm hơn.
Quick sort trung bình O(n log n) nhưng xấu nhất O(n²) nếu chọn chốt kém. Hash map trung bình O(1) nhưng xấu nhất O(n) nếu nhiều khóa đụng độ. Khi trả lời, hãy nêu rõ bạn đang nói trường hợp nào.
Hãy xác định độ phức tạp của đoạn code sau:
function f(n) { let count = 0; for (let i = 1; i < n; i *= 2) { for (let j = 0; j < n; j++) { count++; } } return count;}Vòng lặp ngoài nhân đôi i mỗi lần nên chạy khoảng log n lần, vòng trong chạy n lần mỗi lượt. Tổng cộng là O(n log n). Nếu bạn tự suy ra được kết quả này và giải thích bằng lời, bạn đã nắm khá chắc phần phân tích cơ bản. Hãy thử biến đổi đoạn code, chẳng hạn cho j chạy tới i thay vì n, và xem độ phức tạp thay đổi thế nào.
Big O là ngôn ngữ chung để bàn về hiệu quả. Hãy tập gắn độ phức tạp cho mọi hàm bạn viết trong vài tuần, bạn sẽ thấy nó trở thành phản xạ tự nhiên.
Nếu muốn luyện thuật toán có hệ thống từ cơ bản, bạn có thể bắt đầu với các khóa học tại codebem.com.
Nguyễn Đình Cường
0 comment