Thuật toán & Cấu trúc dữ liệu/Nền tảng thuật toán/Độ phức tạp thuật toán — Big-O Notation
1/2
~15 phútNền tảng thuật toán

Độ phức tạp thuật toán — Big-O Notation

Hiểu Big-O từ bản chất: tại sao cần đo, cách phân tích, các complexity class phổ biến.

Tại sao cần Big-O?

Cùng bài toán, 2 cách giải có thể khác nhau hàng triệu lần về tốc độ khi input lớn.

Big-O đo tốc độ tăng của thời gian chạy theo input size n.

Các Complexity Class

O(1)       — Constant    : HashMap.get()
O(log n)   — Logarithmic : Binary Search
O(n)       — Linear      : Array scan
O(n log n) — Linearithmic: Merge Sort, Quick Sort (avg)
O(n²)      — Quadratic   : Bubble Sort, nested loops
O(2ⁿ)      — Exponential : Brute-force subsets
O(n!)      — Factorial   : Brute-force permutations

Phân tích ví dụ

// O(n) — linear scan
public int findMax(int[] arr) {
    int max = arr[0];
    for (int x : arr) {        // n iterations
        if (x > max) max = x;  // O(1) per iteration
    }
    return max;
}

// O(n²) — nested loops
public boolean hasDuplicate(int[] arr) {
    for (int i = 0; i < arr.length; i++) {         // n
        for (int j = i + 1; j < arr.length; j++) { // n
            if (arr[i] == arr[j]) return true;
        }
    }
    return false;
}

// O(n) — HashSet approach (trade space for time)
public boolean hasDuplicateFast(int[] arr) {
    Set<Integer> seen = new HashSet<>();
    for (int x : arr) {
        if (!seen.add(x)) return true; // O(1) per lookup
    }
    return false;
}

Key insight: Big-O bỏ qua constants. O(2n) = O(n). Nhưng trong thực tế, constants matter — đó là lý do QuickSort nhanh hơn MergeSort dù cùng O(n log n).