Big O là gì?
Big O mô tả tốc độ tăng trưởng của thời gian chạy khi dữ liệu lớn lên. Không đo “chạy bao nhiêu giây”, mà đo “khi dữ liệu gấp đôi, thời gian tăng bao nhiêu lần?”.
| Big O | Tên gọi | Ví dụ | 100 phần tử | 10.000 phần tử |
|---|---|---|---|---|
| O(1) | Hằng số | Truy cập mảng theo index | 1 thao tác | 1 thao tác |
| O(log n) | Logarit | Binary search | 7 thao tác | 14 thao tác |
| O(n) | Tuyến tính | Duyệt mảng 1 lần | 100 thao tác | 10.000 thao tác |
| O(n log n) | N log N | Merge sort, Quick sort | 700 thao tác | 140.000 thao tác |
| O(n²) | Bình phương | Bubble sort, 2 vòng lặp lồng | 10.000 thao tác | 100.000.000 thao tác |
| O(2ⁿ) | Mũ | Fibonacci đệ quy (chưa tối ưu) | Vô cùng chậm | 💀 Không bao giờ xong |
Nhận diện Big O từ code
// File: bigo.js
// O(1) — Hằng số: không phụ thuộc kích thước mảng
function getFirst(arr) {
return arr[0]
}
// O(n) — Tuyến tính: duyệt mảng 1 lần
function findMax(arr) {
let max = arr[0]
for (const num of arr) {
if (num > max) max = num
}
return max
}
// O(n²) — Bình phương: 2 vòng lặp lồng nhau
function hasDuplicate(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) return true
}
}
return false
}
// O(n) — dùng Set thay vì 2 vòng lặp → nhanh hơn!
function hasDuplicateFast(arr) {
const seen = new Set()
for (const num of arr) {
if (seen.has(num)) return true
seen.add(num)
}
return false
}
1 vòng lặp = O(n). 2 vòng lặp lồng nhau = O(n²). Chia đôi mỗi bước = O(log n). Không có vòng lặp = O(1). Big O chỉ giữ phần lớn nhất: O(n² + n) = O(n²) vì khi n lớn, n² “nuốt” n.
Binary Search: sức mạnh của O(log n)
Tìm số trong mảng đã sắp xếp: thay vì duyệt từ đầu (O(n)), chia đôi mỗi bước. Mảng 1 triệu phần tử? Chỉ cần ~20 bước thay vì 1 triệu bước.
// File: binary-search.js
// Binary Search: tìm trong mảng ĐÃ SẮP XẾP
function binarySearch(arr, target) {
let left = 0
let right = arr.length - 1
while (left <= right) {
const mid = Math.floor((left + right) / 2)
if (arr[mid] === target) return mid // Tìm thấy!
if (arr[mid] < target) left = mid + 1 // Target ở nửa phải
else right = mid - 1 // Target ở nửa trái
}
return -1 // Không tìm thấy
}
const sorted = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
console.log(binarySearch(sorted, 23)) // 5 (index)
❓ Hàm có 2 vòng lặp lồng nhau, mỗi vòng chạy n lần. Big O là?
- Giải thích Big O bằng ví dụ thực tế
- Nhận diện O(1), O(n), O(n²), O(log n) từ code
- Triển khai Binary Search
- Biết vì sao O(n²) chậm hơn O(n log n) khi n lớn