Complexity Analysis — Big-O, Θ, Ω

চালু করার আগেই গতি সম্পর্কে যুক্তি

~45 min Advanced 15 practice problems Live code

1. Why Reason Mathematically?

O(n²) প্রোগ্রাম n = 100-এ ঠিক চলে, n = 10⁶-এ মরে। সব case benchmark করা সম্ভব না। Big-O দিয়ে — code চালানোর আগেই — scalability সম্পর্কে যুক্তি দেওয়া যায়।

2. Formal Definitions

NotationMeaning
f(n) = O(g(n))upper bound — f g-এর চেয়ে দ্রুত বাড়ে না
f(n) = Ω(g(n))lower bound — f অন্তত g-এর মতো দ্রুত বাড়ে
f(n) = Θ(g(n))tight bound — একই growth rate
f(n) = o(g(n))strictly slower growth

Formally: f(n) = O(g(n)) iff ∃ c > 0, n₀ ≥ 0 such that ∀ n ≥ n₀: f(n) ≤ c · g(n)।

3. Common Complexity Classes

O(1)         constant         — array index
O(log n)     logarithmic      — binary search
O(n)         linear           — single pass
O(n log n)   linearithmic     — merge sort
O(n²)        quadratic        — nested loop
O(n³)        cubic            — triple loop
O(2ⁿ)        exponential      — naive Fibonacci
O(n!)        factorial        — all permutations

4. Empirical Measurement

কোড চালিয়ে আসলেই কত সময় লাগে দেখা যাক — linear vs quadratic-এর পার্থক্য স্পষ্ট।

bench.c
#include <stdio.h>
#include <time.h>

long linear(int n) {
    long s = 0;
    for (int i = 0; i < n; i++) s += i;
    return s;
}

long quadratic(int n) {
    long s = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) s += 1;
    return s;
}

int main(void) {
    int sizes[] = { 1000, 5000, 10000 };
    for (int i = 0; i < 3; i++) {
        int n = sizes[i];
        clock_t t1 = clock();   linear(n);    clock_t t2 = clock();
        clock_t t3 = clock();   quadratic(n); clock_t t4 = clock();
        printf("n=%d  linear=%.3fms  quadratic=%.3fms\n",
               n,
               1000.0 * (t2 - t1) / CLOCKS_PER_SEC,
               1000.0 * (t4 - t3) / CLOCKS_PER_SEC);
    }
    return 0;
}

n দ্বিগুণ করলে linear ~2x সময়, quadratic ~4x সময়। Online compiler-এ timing variable — প্যাটার্ন-ই দেখুন।

5. Analyzing Code

for (int i = 0; i < n; i++)         // O(n)
    for (int j = 0; j < n; j++)     // O(n)
        for (int k = 1; k < n; k *= 2) // O(log n)
            ...                         // total: O(n² log n)

6. Amortized Analysis

Dynamic array append worst case O(n) (যখন realloc দ্বিগুণ হয়), কিন্তু n-বার append-এর মোট কাজ O(n) — per-operation amortized O(1)।

Aggregate method n-operation-এর মোট খরচ সমষ্টি করে n দিয়ে ভাগ করুন — amortized cost।

7. Master Theorem

T(n) = aT(n/b) + f(n)

f(n) vs n^log_b(a):
  Case 1: f smaller → T = Θ(n^log_b(a))
  Case 2: same     → T = Θ(n^log_b(a) · log n)
  Case 3: f larger → T = Θ(f(n))

Example: Merge sort T(n) = 2T(n/2) + n
  log_2(2) = 1, f(n) = n → Case 2 → T(n) = Θ(n log n)

8. Contest Time Budget (1 second)

nFits
10⁸O(n)
10⁷O(n log n)
10⁴O(n²)
500O(n³)
25O(2ⁿ)
10O(n!)

9. Practice Problems

  1. Give Big-O of: single loop to n; nested loops; while (n >= 1) n /= 2;.
    Complexity বলুন।
    ✨ Show Answer

    O(n), O(n²), O(log n)।

  2. Prove 3n² + 5n + 7 = O(n²) using the formal definition.
    Formal definition দিয়ে প্রমাণ।
    ✨ Show Answer

    n ≥ 1-এর জন্য 3n² + 5n + 7 ≤ 3n² + 5n² + 7n² = 15n²। অর্থাৎ c = 15, n₀ = 1 নিলেই 3n² + 5n + 7 ≤ 15n² হয় — তাই O(n²)। ∎

  3. Big-O of merge sort with Master Theorem.
    Merge sort-এর complexity।
    ✨ Show Answer

    T(n) = 2T(n/2) + Θ(n) → Master Theorem Case 2 → Θ(n log n)।

  4. Worst/best/average of quicksort.
    Quicksort-এর সব case।
    ✨ Show Answer

    Worst O(n²) (already-sorted + fixed pivot)। Average & best O(n log n)। Random pivot-এ worst case avoid হয়।

  5. Space complexity of recursive factorial.
    Recursive factorial-এর space।
    ✨ Show Answer

    Recursion depth n → stack O(n)। Iterative version O(1)।

  6. Amortized cost of n pushes into dynamic array.
    n-বার dynamic-array push-এর amortized cost।
    ✨ Show Answer

    Resize-এর সময় 1 + 2 + 4 + … + n ≈ 2n কাজ — মোট O(n), per-push O(1) amortized।

  7. Compare bubble vs merge sort for n = 10⁵.
    n = 10⁵-এ bubble vs merge।
    ✨ Show Answer

    Bubble ~10¹⁰ operations (কয়েক মিনিট)। Merge ~10⁵ × 17 = 1.7×10⁶ (মিলিসেকেন্ড)। প্রায় ১০০০০ গুণ পার্থক্য।

  8. Given 2 sec budget, what algorithmic class fits n = 10⁶?
    2 সেকেন্ডে n = 10⁶-এ কোন class?
    ✨ Show Answer

    ~2×10⁸ operations budget। O(n log n) (n·20 ≈ 2×10⁷) — আরামদায়ক। O(n²) বাদ।

  9. Big-O of traversing a binary tree.
    Tree traversal-এর Big-O।
    ✨ Show Answer

    প্রতিটি node একবার visit — O(n)। Stack space: worst O(n) (skewed), balanced O(log n)।

  10. Big-O of BFS and DFS.
    BFS/DFS-এর Big-O।
    ✨ Show Answer

    O(V + E) — প্রতিটি vertex ও edge একবার করে visit।

  11. Big-O of naive Fibonacci vs memoized.
    Naive ও memoized Fibonacci।
    ✨ Show Answer

    Naive O(2ⁿ) — subproblems-এ exponential repetition। Memoized O(n) — প্রতিটি subproblem একবার গণনা।

  12. Is O(n + m) the same as O(n)?
    O(n+m) ও O(n) কি এক?
    ✨ Show Answer

    যদি m = O(n) হয়, তবে হ্যাঁ। কিন্তু যদি m স্বাধীন ভেরিয়েবল হয় (গ্রাফে V, E যেমন), তাহলে না — দুটি আলাদা parameter।

  13. Does O(2n) = O(n)? Why?
    O(2n) = O(n) কেন?
    ✨ Show Answer

    Big-O constant factor উপেক্ষা করে: c = 2 এই definition-এই কাজ করে। Asymptotically একই class।

  14. Solve T(n) = 2T(n/2) + n using Master Theorem.
    Master Theorem দিয়ে সমাধান।
    ✨ Show Answer

    log_2(2) = 1, f(n) = n = n¹ — Case 2 → T(n) = Θ(n log n)।

  15. Measure empirically: time sort on n = 10³, 10⁴, 10⁵; fit the curve.
    Sort-এর runtime পরিমাপ করুন।
    ✨ Show Answer

    Section 4-এর bench.c ধাঁচের কোড লিখুন — clock_gettime(CLOCK_MONOTONIC, ...) ব্যবহার করলে আরও নির্ভুল timing। Log-log plot-এ slope = complexity exponent।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
Asymptotic AnalysisStudying behavior as input size grows toward infinity.Input বিশাল হলে আচরণ কী — তার বিশ্লেষণ।
Big-O (O)Upper bound on growth rate.বৃদ্ধির ঊর্ধ্বসীমা।
Big-Omega (Ω)Lower bound on growth rate.বৃদ্ধির নিম্নসীমা।
Big-Theta (Θ)Tight bound — both upper and lower.উভয় দিক থেকে আঁটসাঁট সীমা।
Time ComplexityHow runtime scales with input size.Runtime কীভাবে input-এর সাথে বাড়ে।
Space ComplexityHow memory use scales with input size.Memory ব্যবহার কীভাবে বাড়ে।
Constant Time — O(1)Cost does not grow with n.n-এর সাথে cost বাড়ে না।
Logarithmic — O(log n)Halves the search space each step.প্রতি ধাপে অর্ধেক করে।
Linear — O(n)Cost grows in proportion to n.n-এর সাথে সমানুপাতিক।
Linearithmic — O(n log n)Common for fast sorts.দ্রুত sort-এর সাধারণ complexity।
Quadratic — O(n²)Cost grows with the square of n.n²-এর হারে বাড়ে।
Exponential — O(2ⁿ)Doubles for every extra input.প্রতি অতিরিক্ত input-এ দ্বিগুণ।
Worst / Best / AverageThe three cases for analyzing algorithms.Algorithm বিশ্লেষণের তিন ক্ষেত্র।
AmortizedAverage cost over a sequence of operations.একটি ক্রমিক operation-এর গড় cost।

Summary — Module 30

Big-O constant আর lower-order term লুকায়; দেখায় cost কীভাবে বাড়ে। Classes ও n-budget জানাই algorithmic thinking-এর ভিত্তি।

Next Module → Sorting Algorithms।