🚀 DSA āϜāĻžāĻ°ā§āύāĻŋ: āϟāĻžāχāĻŽ āĻāĻŦāĻ‚ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ (Time & Space Complexity)

āĻĄā§‡āϟāĻž āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ (DSA) āĻļ⧇āĻ–āĻžāϰ āĻĒā§āϰāĻĨāĻŽ āĻāĻŦāĻ‚ āϏāĻŦāĻĨ⧇āϕ⧇ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āϧāĻžāĻĒ āĻšāϞ⧋ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ āĻ…ā§āϝāĻžāύāĻžāϞāĻžāχāϏāĻŋāϏ āĻ•āϰāĻžāĨ¤ āĻāχ āϰāĻŋāĻĒā§‹āϜāĻŋāϟāϰāĻŋāϤ⧇ āφāĻŽāĻŋ āϟāĻžāχāĻŽ āĻāĻŦāĻ‚ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āύāĻŋā§Ÿā§‡ āφāĻŽāĻžāϰ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϞāĻžāĻ°ā§āύāĻŋāĻ‚ āύ⧋āϟāϏ āĻļā§‡ā§ŸāĻžāϰ āĻ•āϰāĻ›āĻŋāĨ¤

📌 āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ (Time Complexity) āĻ•āĻŋ?

āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻŽāĻžāύ⧇ āĻāχ āύ⧟ āϝ⧇ āϕ⧋āĻĄ āϰāĻžāύ āĻšāϤ⧇ āĻ•āϤ āϏ⧇āϕ⧇āĻ¨ā§āĻĄ āϏāĻŽā§Ÿ āϞāĻžāĻ—āϛ⧇āĨ¤ āĻŦāϰāĻ‚, āχāύāĻĒ⧁āϟ āϏāĻžāχāϜ ($n$) āĻŦāĻžā§œāĻžāϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāϟāĻŋ āϰāĻžāύ āĻšāϤ⧇ āϕ⧇āĻŽāύ āϏāĻŽā§Ÿ āύ⧇āĻŦ⧇, āϤāĻžāϰ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻžāϰāϕ⧇ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻŦāϞ⧇āĨ¤

āĻ•āĻŽāύ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āύ⧋āĻŸā§‡āĻļāύāϏāĻŽā§‚āĻš:

ā§§. $O(1)$ - āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āϟāĻžāχāĻŽ (Constant Time)

āχāύāĻĒ⧁āϟ āϝāĻžāχ āĻšā§‹āĻ• āύāĻž āϕ⧇āύ, āĻ•āĻžāϜ āϏāĻŦāϏāĻŽā§Ÿ āĻāĻ•āχ āϏāĻŽā§Ÿā§‡ āĻļ⧇āώ āĻšā§ŸāĨ¤

int a = 10, b = 20;
int sum = a + b; // āĻāϟāĻŋ āϏāĻŦāϏāĻŽā§Ÿ O(1)

⧍. $O(\log n)$ - āϞāĻ—āĻžāϰāĻŋāĻĻāĻŽāĻŋāĻ• āϟāĻžāχāĻŽ (Logarithmic Time)

āĻĒā§āϰāϤāĻŋ āϧāĻžāĻĒ⧇ āχāύāĻĒ⧁āϟ āĻ…āĻ°ā§āϧ⧇āĻ• āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤ āĻāϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āĻĻā§āϰ⧁āϤāĨ¤

for (int i = n; i > 1; i = i / 2) {
    cout << i; // āĻāϟāĻŋ O(log n)
}

ā§Š. $O(n)$ - āϞāĻŋāύāĻŋ⧟āĻžāϰ āϟāĻžāχāĻŽ (Linear Time)

āχāύāĻĒ⧁āϟ āϝāϤ āĻŦāĻžā§œāĻŦ⧇, āϏāĻŽā§ŸāĻ“ āĻ āĻŋāĻ• āϤāϤāϟ⧁āϕ⧁āχ āĻŦāĻžā§œāĻŦ⧇āĨ¤ āĻāĻ•āϟāĻŋ āϞ⧁āĻĒ āĻĨāĻžāĻ•āϞ⧇ āĻāĻŽāύ āĻšā§ŸāĨ¤

for (int i = 0; i < n; i++) {
    cout << i; // n āĻŦāĻžāϰ āϚāϞāĻŦ⧇
}

ā§Ē. $O(n \log n)$ - āϞāĻŋāύāĻŋ⧟āĻžāϰāĻŋāĻĨāĻŽāĻŋāĻ• āϟāĻžāχāĻŽ (Linearithmic Time)

āĻāĻ•āϟāĻŋ $n$ āĻŦāĻžāϰ⧇āϰ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ āϝāĻĻāĻŋ āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ $\log n$ āĻ•āĻžāϜ āĻšā§ŸāĨ¤ āϏāĻ°ā§āϟāĻŋāĻ‚ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽā§‡ (Merge Sort) āĻāϟāĻŋ āĻĻ⧇āĻ–āĻž āϝāĻžā§ŸāĨ¤ āϏāĻšāϜ āĻ•āĻĨāĻžā§Ÿ, āĻāϟāĻŋ $O(n)$ āĻāĻŦāĻ‚ $O(\log n)$ āĻāϰ āϗ⧁āĻŖāĻĢāϞāĨ¤

// āĻŦāĻžāχāϰ⧇āϰ āϞ⧁āĻĒāϟāĻŋ n āĻŦāĻžāϰ āϚāϞ⧇ -> O(n)
for (int i = 0; i < n; i++) {

    // āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒāϟāĻŋ āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻ…āĻ°ā§āϧ⧇āĻ• āĻšā§Ÿā§‡ āϝāĻžāĻšā§āϛ⧇ -> O(log n)
    for (int j = n; j > 1; j = j / 2) {
        cout << "Working...";
    }
}

āĻāĻ–āĻžāύ⧇ āĻŸā§‹āϟāĻžāϞ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāĻŦ⧇ $n \times \log n = O(n \log n)$āĨ¤

ā§Ģ. $O(n^2)$ - āϕ⧋āϝāĻŧāĻžāĻĄā§āϰāĻžāϟāĻŋāĻ• āϟāĻžāχāĻŽ (Quadratic Time)

āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ āϞ⧁āĻĒ āĻĨāĻžāĻ•āϞ⧇ (Nested Loop) āĻāĻŽāύ āĻšā§ŸāĨ¤ āχāύāĻĒ⧁āϟ āĻĻā§āĻŦāĻŋāϗ⧁āĻŖ āĻšāϞ⧇ āϏāĻŽā§Ÿ āϚāĻžāϰāϗ⧁āĻŖ āĻŦā§‡ā§œā§‡ āϝāĻžā§ŸāĨ¤

for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        cout << i << j; // n * n āĻŦāĻžāϰ āϚāϞāĻŦ⧇
    }
}

6. Cubic Time Complexity — $O(n^3)$

āĻāϟāĻŋ āĻŽā§‚āϞāϤ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āϞ⧁āĻĒāĨ¤ āĻ…āĻ°ā§āĻĨāĻžā§Ž ā§ŠāϟāĻŋ āϞ⧁āĻĒ āĻāϕ⧇ āĻ…āĻĒāϰ⧇āϰ āϭ⧇āϤāϰ⧇ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤

for (int i = 0; i < n; i++) {           // ā§§āĻŽ āϞ⧁āĻĒ (n āĻŦāĻžāϰ)
    for (int j = 0; j < n; j++) {       // ⧍⧟ āϞ⧁āĻĒ (n āĻŦāĻžāϰ)
        for (int k = 0; k < n; k++) {   // ā§Šā§Ÿ āϞ⧁āĻĒ (n āĻŦāĻžāϰ)
            cout << i << j << k;
        }
    }
}

7. Time Complexity with Two Variables — $O(n \times k)$

āϏāĻŦ āϏāĻŽā§Ÿ āϝ⧇ āχāύāĻĒ⧁āϟ āĻļ⧁āϧ⧁ āĻāĻ•āϟāĻžāχ ($n$) āĻšāĻŦ⧇ āϤāĻž āĻ•āĻŋāĻ¨ā§āϤ⧁ āύ⧟āĨ¤ āĻ•āĻ–āύ⧋ āĻ•āĻ–āύ⧋ āφāĻĒāύāĻžāϰ āϕ⧋āĻĄ āĻĻ⧁āϟāĻŋ āφāϞāĻžāĻĻāĻž āχāύāĻĒ⧁āĻŸā§‡āϰ āĻ“āĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇āĨ¤

āωāĻĻāĻžāĻšāϰāĻŖ: āϧāϰ⧁āύ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ $n$ āϏāĻ‚āĻ–ā§āϝāĻ• āĻ›āĻžāĻ¤ā§āϰ āφāϛ⧇ āĻāĻŦāĻ‚ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ›āĻžāĻ¤ā§āϰ⧇āϰ $k$ āϟāĻŋ āĻ•āϰ⧇ āϏāĻžāĻŦāĻœā§‡āĻ•ā§āϟ āφāϛ⧇āĨ¤ āφāĻĒāύāĻŋ āϏāĻŦāĻžāϰ āϏāĻŦ āϏāĻžāĻŦāĻœā§‡āĻ•ā§āϟ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āĻ•āϰāĻŦ⧇āύāĨ¤

void printGrades(int n, int k) {
    for (int i = 0; i < n; i++) {       // n āĻŦāĻžāϰ āϚāϞ⧇
        for (int j = 0; j < k; j++) {   // k āĻŦāĻžāϰ āϚāϞ⧇
            cout << "Student " << i << " Subject " << j;
        }
    }
}

âš–ī¸ āĻ•ā§āϝāĻžāϞāϕ⧁āϞ⧇āĻļāύ āĻ•āϰāĻžāϰ āϏāĻšāϜ āύāĻŋ⧟āĻŽ

  1. āϝ⧋āϗ⧇āϰ āύāĻŋ⧟āĻŽ (Addition): āϝāĻĻāĻŋ āφāϞāĻžāĻĻāĻž āφāϞāĻžāĻĻāĻž āϞ⧁āĻĒ āĻĨāĻžāϕ⧇: O(n) + O(n) = O(2n) -> O(n) (āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ ⧍ āĻŦāĻžāĻĻ āϝāĻžāĻŦ⧇)āĨ¤
  2. āϗ⧁āϪ⧇āϰ āύāĻŋ⧟āĻŽ (Multiplication): āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ āϞ⧁āĻĒ āĻĨāĻžāĻ•āϞ⧇: n * n = O(n^2)āĨ¤

  3. āĻŦ⧜ āĻĒāĻžāĻ“ā§ŸāĻžāϰ āϰāĻžāĻ–āĻž: āϝāĻĻāĻŋ āϰ⧇āϜāĻžāĻ˛ā§āϟ āĻšā§Ÿ O(n^2 + n + 1), āφāĻŽāϰāĻž āĻļ⧁āϧ⧁ āĻŦ⧜āϟāĻŋ āϰāĻžāĻ–āĻŦ: O(n^2)āĨ¤

💾 āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ (Space Complexity)

āϕ⧋āĻĄ āϰāĻžāύ āĻ•āϰāĻžāϰ āϏāĻŽā§Ÿ āĻŽā§‡āĻŽā§‹āϰāĻŋāϤ⧇ (RAM) āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻ•āϤāϟ⧁āϕ⧁ āϜāĻžā§ŸāĻ—āĻž āϞāĻžāĻ—āϛ⧇ āϏ⧇āϟāĻžāχ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋāĨ¤

**āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāϗ⧁āϞ⧋āϰ āĻŽāĻ§ā§āϝ⧇ Binary Search āĻšāϞ⧋ āĻ…āĻ¨ā§āϝāϤāĻŽ āϏ⧇āϰāĻž āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ āϝāĻž āϖ⧁āĻŦ āĻĻā§āϰ⧁āϤ āĻ•āĻžāϜ āĻ•āϰ⧇āĨ¤ āϚāϞ⧁āύ āϏāĻšāϜāĻ­āĻžāĻŦ⧇ āĻŦ⧁āĻāĻŋ āϕ⧇āύ āĻāϟāĻŋ $O(\log n)$: **

  1. āĻ•āĻžāĻœā§‡āϰ āĻĒāĻĻā§āϧāϤāĻŋ (Divide and Conquer) āĻŦāĻžāχāύāĻžāϰāĻŋ āϏāĻžāĻ°ā§āĻšā§‡āϰ āĻŽā§‚āϞ āφāχāĻĄāĻŋ⧟āĻž āĻšāϞ⧋ āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻšā§‡āĻ• āĻ•āϰāĻžāϰ āĻĒāϰ āφāĻŽāϰāĻž āĻĄā§‡āϟāĻžāϏ⧇āϟ āĻŦāĻž āĻ…ā§āϝāĻžāϰ⧇āϟāĻŋāϕ⧇ āĻ…āĻ°ā§āϧ⧇āĻ• (Half) āĻ•āϰ⧇ āĻĢ⧇āϞāĻŋāĨ¤
    • āϧāϰ⧁āύ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ ā§§ā§Ļā§ĻāϟāĻŋ āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āϟ āφāϛ⧇āĨ¤
    • āĻĒā§āϰāĻĨāĻŽāĻŦāĻžāϰ āĻšā§‡āĻ• āĻ•āϰāĻžāϰ āĻĒāϰ āϝāĻĻāĻŋ āĻ•āĻžāĻ™ā§āĻ•ā§āώāĻŋāϤ āĻ­ā§āϝāĻžāϞ⧁āϟāĻŋ āύāĻž āĻĒāĻžāύ, āϤāĻŦ⧇ āφāĻĒāύāĻŋ āĻŦāĻžāĻ•āĻŋ ā§Ģā§ĻāϟāĻŋ āĻŦāĻžāĻĻ āĻĻāĻŋā§Ÿā§‡ āĻĻāĻŋāĻšā§āϛ⧇āύāĨ¤
    • āĻāϰāĻĒāϰ ⧍ā§ĢāϟāĻŋ, āϤāĻžāϰāĻĒāϰ ⧧⧍āϟāĻŋâ€Ļ āĻāĻ­āĻžāĻŦ⧇ āϖ⧁āĻŦ āĻĻā§āϰ⧁āϤ āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āϟāĻžāĻ°ā§āϗ⧇āĻŸā§‡ āĻĒ⧌āρāϛ⧇ āϝāĻžāύāĨ¤
  2. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦāϧāϰāĻŋ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ $n$ āϏāĻ‚āĻ–ā§āϝāĻ• āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āϟ āφāϛ⧇ āĻāĻŦāĻ‚ $k$ āĻŦāĻžāϰ āϏāĻžāĻ°ā§āϚ āĻ•āϰāĻžāϰ āĻĒāϰ āφāĻŽāϰāĻž āĻ­ā§āϝāĻžāϞ⧁āϟāĻŋ āϖ⧁āρāĻœā§‡ āĻĒ⧇āϞāĻžāĻŽāĨ¤ āϝ⧇āĻšā§‡āϤ⧁ āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āφāĻŽāϰāĻž ⧍ āĻĻāĻŋā§Ÿā§‡ āĻ­āĻžāĻ— āĻ•āϰāĻ›āĻŋ, āϤāĻžāχ:

\(\frac{n}{2^k} = 1\) \((n = 2^k)\)

āĻāĻ–āĻžāύ⧇ āωāϭ⧟ āĻĒāĻžāĻļ⧇ Log āύāĻŋāϞ⧇ āφāĻŽāϰāĻž āĻĒāĻžāχ: \(\log_2(n) = k\)

āĻ…āĻ°ā§āĻĨāĻžā§Ž, āφāĻŽāϰāĻž $n$ āϕ⧇ āĻ•āϤāĻŦāĻžāϰ ⧍ āĻĻāĻŋā§Ÿā§‡ āĻ­āĻžāĻ— āĻ•āϰāϞ⧇ ā§§-āĻ āĻĒ⧌āρāĻ›āĻžāĻŦā§‹? āωāĻ¤ā§āϤāϰ āĻšāϞ⧋ $\log_2 n$ āĻŦāĻžāϰāĨ¤ āĻāĻ•āĻžāϰāϪ⧇āχ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ $O(\log n)$āĨ¤

Big-O ($O$): The Upper Bound (āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āϏ⧀āĻŽāĻž)

Big-O āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰ⧇ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻ•āϤ āϏāĻŽā§Ÿ āύāĻŋāϤ⧇ āĻĒāĻžāϰ⧇ (Worst Case)āĨ¤ āĻāϟāĻŋ āφāĻŽāĻžāĻĻ⧇āϰ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ āĻĻā§‡ā§Ÿ āϝ⧇, “āĻ­āĻžāχ, āĻāχ āϕ⧋āĻĄāϟāĻž āϰāĻžāύ āĻšāϤ⧇ āĻāϰ āĻšā§‡ā§Ÿā§‡ āĻŦ⧇āĻļāĻŋ āϏāĻŽā§Ÿ āφāϰ āϞāĻžāĻ—āĻŦ⧇ āύāĻžāĨ¤â€

Big-Theta ($\Theta$): The Tight Bound (āĻāĻ•āĻĻāĻŽ āϏāĻ āĻŋāĻ• āϏ⧀āĻŽāĻž)

Big-Theta āĻšāϞ⧋ āφāϰāĻ“ āĻŦ⧇āĻļāĻŋ āϏ⧁āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟāĨ¤ āĻāϟāĻŋ āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰ⧇ āϝ⧇ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāϟāĻŋ āϏāĻŦāϏāĻŽā§Ÿ āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āϏ⧀āĻŽāĻžāϰ āĻŽāĻ§ā§āϝ⧇āχ āĻ•āĻžāϜ āĻ•āϰāĻŦ⧇āĨ¤ āĻāϟāĻŋ Upper Bound āĻāĻŦāĻ‚ Lower Bound āĻĻ⧁āĻŸā§‹āϰ āϏāĻŽāĻ¨ā§āĻŦāϝāĻŧāĨ¤

āĻāĻ•āϟāĻŋ āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ āĻĻāĻŋā§Ÿā§‡ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āĻŦ⧁āĻā§āύ:

āϧāϰ⧁āύ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϰ⧇ āφāϛ⧇ āĻāĻŦāĻ‚ āφāĻĒāύāĻŋ āϏ⧇āĻ–āĻžāύ⧇ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž āϖ⧁āρāϜāϛ⧇āύ (Linear Search):

Big-Omega ($\Omega$)

Big-Omega āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰ⧇ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ āϰāĻžāύ āĻšāϤ⧇ āĻ•āĻŽāĻĒāĻ•ā§āώ⧇ āĻŦāĻž āϏāĻ°ā§āĻŦāύāĻŋāĻŽā§āύ (Best Case) āĻ•āϤāϟ⧁āϕ⧁ āϏāĻŽā§Ÿ āύ⧇āĻŦ⧇āĨ¤ āĻāϟāĻŋ āĻšāϞ⧋ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽā§‡āϰ Lower BoundāĨ¤

āϧāϰāĻž āϝāĻžāĻ•, āĻāĻ•āϟāĻž āĻ…ā§āϝāĻžāϰ⧇āϤ⧇ āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž āϖ⧁āρāϜāϛ⧇āύāĨ¤

What is the time complexity of the best-known algorithm for matrix multiplication of two n×n matrices?

  1. āϏāĻžāϧāĻžāϰāĻŖ āύāĻŋ⧟āĻŽ ($O(n^3)$):āφāĻŽāϰāĻž āĻ¸ā§āϕ⧁āϞ-āĻ•āϞ⧇āĻœā§‡ āϝ⧇āĻ­āĻžāĻŦ⧇ āĻŽā§āϝāĻžāĻŸā§āϰāĻŋāĻ•ā§āϏ āϗ⧁āĻŖ āĻ•āϰāĻž āĻļāĻŋāĻ–āĻŋ (Row āĻĻāĻŋā§Ÿā§‡ Column-āϕ⧇ āϗ⧁āĻŖ), āϏ⧇āχ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ āĻĻ⧁āϟāĻŋ $n \times n$ āĻŽā§āϝāĻžāĻŸā§āϰāĻŋāĻ•ā§āϏ āϗ⧁āĻŖ āĻ•āϰāϞ⧇ āφāĻŽāĻžāĻĻ⧇āϰ ā§ŠāϟāĻŋ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āϞ⧁āĻĒ āϞāĻžāϗ⧇āĨ¤ āϤāĻžāχ āĻāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšā§Ÿ $O(n^3)$āĨ¤

  2. āĻ¸ā§āĻŸā§āĻ°ā§āϝāĻžāϏ⧇āύ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ (Strassen’s Algorithm):⧧⧝ā§Ŧ⧝ āϏāĻžāϞ⧇ āĻ­āϞāĻ•āĻžāϰ āĻ¸ā§āĻŸā§āĻ°ā§āϝāĻžāϏ⧇āύ āĻĻ⧇āĻ–āĻžāύ āϝ⧇, āĻŽā§āϝāĻžāĻŸā§āϰāĻŋāĻ•ā§āϏ āϗ⧁āĻŖāύ $O(n^3)$ āĻāϰ āĻšā§‡ā§Ÿā§‡āĻ“ āĻĻā§āϰ⧁āϤ āĻ•āϰāĻž āϏāĻŽā§āĻ­āĻŦāĨ¤ āϤāĻŋāύāĻŋ āĻāĻ•āϟāĻŋ āĻŦāĻŋāĻļ⧇āώ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻŸā§āϰāĻŋāĻ• āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϗ⧁āϪ⧇āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻ•āĻŽāĻŋā§Ÿā§‡ āφāύ⧇āύāĨ¤ āϤāĻžāϰ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽā§‡āϰ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻ›āĻŋāϞ āĻĒā§āϰāĻžā§Ÿ $O(n^{2.81})$āĨ¤

  3. āĻŦāĻ°ā§āϤāĻŽāĻžāύ āϏ⧇āϰāĻž āϰ⧇āĻ•āĻ°ā§āĻĄ ($O(n^{2.373})$):āĻ¸ā§āĻŸā§āĻ°ā§āϝāĻžāϏ⧇āύ⧇āϰ āĻĒāϰ āĻ…āύ⧇āĻ• āĻ—āĻŖāĻŋāϤāĻŦāĻŋāĻĻ āĻāϟāĻŋ āφāϰāĻ“ āĻ•āĻŽāĻžāύ⧋āϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇āϛ⧇āύāĨ¤ āĻŦāĻ°ā§āϤāĻŽāĻžāύ⧇ āϏāĻŦāĻĨ⧇āϕ⧇ āĻĒāϰāĻŋāϚāĻŋāϤ āĻāĻŦāĻ‚ āĻĻā§āϰ⧁āϤāϤāĻŽ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāϟāĻŋ āĻšāϞ⧋ Coppersmith–Winograd algorithm (āĻāĻŦāĻ‚ āĻāϰ āφāϧ⧁āύāĻŋāĻ• āĻ­āĻžāĻ°ā§āϏāύāϗ⧁āϞ⧋), āϝāĻžāϰ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻĒā§āϰāĻžā§Ÿ $O(n^{2.373})$āĨ¤

Amortized Complexity āφāϏāϞ⧇ āϕ⧀?

āϏāĻšāϜ āĻ­āĻžāώāĻžā§Ÿ: āϕ⧋āύ⧋ āĻāĻ•āϟāĻŋ āĻ•āĻžāĻœā§‡ āĻŽāĻžāĻā§‡ āĻŽāĻžāĻā§‡ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āϏāĻŽā§Ÿ āϞāĻžāϗ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āϏāĻŽā§Ÿ āϏ⧇āϟāĻŋ āϖ⧁āĻŦ āĻĻā§āϰ⧁āϤ āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤ āĻāχ “āĻŦ⧇āĻļāĻŋ āϏāĻŽā§Ÿâ€ āϞāĻžāĻ—āĻžāϰ āĻ–āϰāϚāϟāĻž āϝāĻ–āύ āĻ…āĻ¨ā§āϝ āϏāĻŦ “āĻĻā§āϰ⧁āϤ āĻšāĻ“ā§ŸāĻžâ€ āĻ•āĻžāĻœā§‡āϰ āĻ“āĻĒāϰ āĻ­āĻžāĻ— āĻ•āϰ⧇ āĻĻ⧇āĻ“ā§ŸāĻž āĻšā§Ÿ, āϤāĻ–āύ āϤāĻžāϕ⧇ Amortized āϏāĻŽā§Ÿ āĻŦāϞ⧇āĨ¤

āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ: Dynamic Array (āϝ⧇āĻŽāύ Vector āĻŦāĻž ArrayList)

āϧāϰ⧁āύ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϰ⧇ āφāϛ⧇ āϝāĻžāϰ āϏāĻžāχāϜ ā§ĒāĨ¤ āφāĻĒāύāĻŋ āĻāϤ⧇ ā§ĒāϟāĻŋ āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āϟ āχāύāϏāĻžāĻ°ā§āϟ āĻ•āϰāϞ⧇āύ āϖ⧁āĻŦ āĻĻā§āϰ⧁āϤ ($O(1)$ āϏāĻŽā§Ÿ)āĨ¤

āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāχ $O(n)$ āĻ•āĻžāϜāϟāĻž āĻ•āĻŋ āϏāĻŦāϏāĻŽā§Ÿ āĻšā§Ÿ? āύāĻž, āĻāϟāĻŋ āϖ⧁āĻŦ āĻ•āĻŽ āϏāĻŽā§Ÿā§‡ āĻāĻ•āĻŦāĻžāϰ āĻšā§ŸāĨ¤

āϕ⧇āύ āĻāϟāĻŋ Average Case āύ⧟?

Worst-CaseāĻāĻ•āĻŦāĻžāϰ⧇ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻ•āϤ āϏāĻŽā§Ÿ āϞāĻžāĻ—āϤ⧇ āĻĒāĻžāϰ⧇ (āϝ⧇āĻŽāύ āϰāĻŋ-āϏāĻžāχāĻœā§‡āϰ āϏāĻŽā§Ÿ $O(n)$)āĨ¤

AmortizedāĻ…āύ⧇āĻ•āϗ⧁āϞ⧋ āĻ…āĻĒāĻžāϰ⧇āĻļāύ āĻļ⧇āώ⧇ āĻ—ā§œāĻĒ⧜āϤāĻž āĻ•āϤ āϏāĻŽā§Ÿ āϞāĻžāĻ—āϞ (āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋāĻĄ $O(1)$)āĨ¤

What is the space complexity of a recursive function that makes n recursive calls in total, with no additional data structures, where each call adds one frame to the call stack?

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻ•āύāϏ⧇āĻĒā§āϟ, āĻ•āĻžāϰāĻŖ āĻ…āύ⧇āĻ• āϏāĻŽā§Ÿ āφāĻŽāϰāĻž āĻŽāύ⧇ āĻ•āϰāĻŋ āϕ⧋āĻĄā§‡ āϕ⧋āύ⧋ āĻ…ā§āϝāĻžāϰ⧇ āĻŦāĻž āϭ⧇āĻ•ā§āϟāϰ āύāĻž āĻĨāĻžāĻ•āϞ⧇ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ $O(1)$ āĻšāĻŦ⧇āĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ Recursion-āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻŦāĻŋāώ⧟āϟāĻŋ āφāϞāĻžāĻĻāĻžāĨ¤

āϕ⧇āύ āĻāϟāĻŋ $O(n)$ āĻšāĻŦ⧇?

āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏ⧇āĻŦ:

āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ āĻĻāĻŋā§Ÿā§‡ āĻŦ⧁āĻā§āύ:

āϧāϰāĻž āϝāĻžāĻ•, ā§§ āĻĨ⧇āϕ⧇ $n$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϏāĻ‚āĻ–ā§āϝāĻžāϰ āϝ⧋āĻ—āĻĢāϞ āĻŦ⧇āϰ āĻ•āϰāĻžāϰ āĻāĻ•āϟāĻŋ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻĢāĻžāĻ‚āĻļāύ:

int sum(int n) {
    if (n == 0) return 0;
    return n + sum(n - 1); // āĻāĻ–āĻžāύ⧇ āύāϤ⧁āύ āĻ•āϞ āĻšāĻšā§āϛ⧇
}

āϝāĻĻāĻŋ $n = 5$ āĻšā§Ÿ, āϤāĻŦ⧇ āĻŽā§‡āĻŽā§‹āϰāĻŋāϤ⧇ sum(5), sum(4), sum(3), sum(2), sum(1) āĻāĻŦāĻ‚ sum(0) — āĻāχ āϏāĻŦāϗ⧁āϞ⧋āϰ āϜāĻ¨ā§āϝ āφāϞāĻžāĻĻāĻž āϜāĻžā§ŸāĻ—āĻž āϞāĻžāĻ—āĻŦ⧇ āϝāϤāĻ•ā§āώāĻŖ āύāĻž āĻļ⧇āώ āĻ•āϞāϟāĻŋ āϤāĻžāϰ āϰ⧇āϜāĻžāĻ˛ā§āϟ āĻĢ⧇āϰāϤ āĻĒāĻžāĻ āĻžāĻšā§āϛ⧇āĨ¤ āϤāĻžāχ āĻāĻ–āĻžāύ⧇ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ $O(n)$āĨ¤

āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āύ⧋āϟ (Tail Recursion): āĻ•āĻŋāϛ⧁ āφāϧ⧁āύāĻŋāĻ• āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ Tail Recursion Optimization āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāχ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻŋā§Ÿā§‡ $O(1)$-āĻ āύāĻŋā§Ÿā§‡ āφāϏāϤ⧇ āĻĒāĻžāϰ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏāĻžāϧāĻžāϰāĻŖ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻāĻŦāĻ‚ āχāĻ¨ā§āϟāĻžāϰāĻ­āĻŋāωāϤ⧇ āωāĻ¤ā§āϤāϰ āϏāĻŦ āϏāĻŽā§Ÿ $O(n)$-āχ āϧāϰāĻž āĻšā§ŸāĨ¤

Cubic Time Complexity

for(int i=0; i<n; i++){
    for(int j=0; j<n; j++){
        for(int k=0; k<n; k++){
            sum +=arr[i][j][k];
        }
    }
}

āϞ⧁āĻĒ⧇āϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ:

āϕ⧋āĻĄāϟāĻŋāϤ⧇ ā§ŠāϟāĻŋ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āϞ⧁āĻĒ (āĻāĻ•āϟāĻŋāϰ āϭ⧇āϤāϰ⧇ āφāϰ⧇āĻ•āϟāĻŋ) āφāϛ⧇:āϏāĻŦāĻšā§‡ā§Ÿā§‡ āĻŦāĻžāχāϰ⧇āϰ āϞ⧁āĻĒ (i):

āĻāϟāĻŋ āĻ•āĻŋ āĻĢāĻžāĻ¸ā§āϟ āύāĻžāĻ•āĻŋ āĻ¸ā§āϞ⧋?

āĻāϟāĻŋ āĻŦ⧇āĻļ āĻ¸ā§āϞ⧋ (Slow) āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋāĨ¤


for(int i=0; i<n; i++){
    for(int j=0; j<m; j++){
            arr[i][j]=0;
    }
}

āϕ⧇āύ āĻāϟāĻŋ $O(n \times m)$?

āĻāĻ–āĻžāύ⧇ āĻĻ⧁āϟāĻŋ āφāϞāĻžāĻĻāĻž āχāύāĻĒ⧁āϟ āĻŦāĻž āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻ•āĻžāϜ āĻ•āϰāϛ⧇:

āϝ⧇āĻšā§‡āϤ⧁ āĻāĻ•āϟāĻŋ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ āφāϰ⧇āĻ•āϟāĻŋ āϞ⧁āĻĒ āφāϛ⧇, āϤāĻžāχ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻšāĻŦ⧇ āϤāĻžāĻĻ⧇āϰ āϗ⧁āĻŖāĻĢāϞ:\(Total\ Operations = n \times m\)āϤāĻžāχ āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇ āĻāϟāĻŋ $O(n \times m)$āĨ¤


int i=n;
while(i>1){
    i=i/2
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(\log n)$ (Logarithmic Time Complexity)āĨ¤

āϕ⧇āύ āĻāϟāĻŋ $O(\log n)$?

āϏāĻšāϜāĻ­āĻžāĻŦ⧇ āĻŦāϞāϞ⧇, āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āϞ⧁āĻĒāϟāĻŋ āϚāϞāĻžāϰ āϏāĻŽā§Ÿ āχāύāĻĒ⧁āϟ $i$ āĻāϰ āĻŽāĻžāύ āĻ…āĻ°ā§āϧ⧇āĻ• āĻšā§Ÿā§‡ āϝāĻžāĻšā§āϛ⧇āĨ¤ āϧāϰāĻž āϝāĻžāĻ•, $n = 16$:

āĻ–ā§‡ā§ŸāĻžāϞ āĻ•āϰ⧁āύ, āχāύāĻĒ⧁āϟ ā§§ā§Ŧ āĻšāϞ⧇āĻ“ āϞ⧁āĻĒ āϚāϞ⧇āϛ⧇ āĻŽāĻžāĻ¤ā§āϰ ā§Ē āĻŦāĻžāϰāĨ¤ āĻ—āĻŖāĻŋāϤ⧇āϰ āĻ­āĻžāώāĻžā§Ÿ, $2^4 = 16$āĨ¤ āĻ…āĻ°ā§āĻĨāĻžā§Ž ā§§ā§Ŧ āϕ⧇ āĻ•āϤāĻŦāĻžāϰ ⧍ āĻĻāĻŋā§Ÿā§‡ āĻ­āĻžāĻ— āĻ•āϰāϞ⧇ ā§§ āĻĒāĻžāĻ“ā§ŸāĻž āϝāĻžā§Ÿ? āωāĻ¤ā§āϤāϰ āĻšāϞ⧋ $\log_2 16 = 4$ āĻŦāĻžāϰāĨ¤

āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ


for(int i=0; i<n; i++){
    for(int j=0; j<n; j=j*2){
            sum++;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n \log n)$āĨ¤

āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻŽā§‹āϟ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ

āϝ⧇āĻšā§‡āϤ⧁ āĻāĻ•āϟāĻŋ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ⧇ āφāϰ⧇āĻ•āϟāĻŋ āϞ⧁āĻĒ āφāϛ⧇, āϤāĻžāχ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻšāĻŦ⧇ āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āϗ⧁āĻŖāĻĢāϞ:

\[Total\ Time = (Outer\ Loop\ Iterations) \times (Inner\ Loop\ Iterations)\] \[Total\ Time = n \times \log n = O(n \log n)\]

āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ

āĻāχ $O(n \log n)$ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋāϟāĻŋ āφāĻĒāύāĻŋ āϏāĻŦāĻšā§‡ā§Ÿā§‡ āĻŦ⧇āĻļāĻŋ āĻĻ⧇āĻ–āĻŦ⧇āύ āĻĻāĻ•ā§āώ āϏāĻ°ā§āϟāĻŋāĻ‚ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāϗ⧁āϞ⧋āϤ⧇, āϝ⧇āĻŽāύ: Merge Sort āĻŦāĻž Quick SortāĨ¤ āĻāϟāĻŋ $O(n^2)$ āĻāϰ āĻšā§‡ā§Ÿā§‡ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āĻĢāĻžāĻ¸ā§āϟ āĻ•āĻŋāĻ¨ā§āϤ⧁ $O(n)$ āĻāϰ āĻšā§‡ā§Ÿā§‡ āĻ•āĻŋāϛ⧁āϟāĻž āĻ¸ā§āϞ⧋āĨ¤


void func(int n){
    if(n<=1)return;
    func(n/2);
    func(n/2);
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n)$āĨ¤

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻĢāĻžāĻ‚āĻļāύ āϝāĻž āĻĻ⧇āϖ⧇ āĻļ⧁āϰ⧁āϤ⧇ āĻ…āύ⧇āϕ⧇āϰāχ āĻŽāύ⧇ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āϝ⧇ āĻāϟāĻŋ $O(\log n)$ āĻšāĻŦ⧇ (āϝ⧇āĻšā§‡āϤ⧁ $n$ āϕ⧇ ⧍ āĻĻāĻŋā§Ÿā§‡ āĻ­āĻžāĻ— āĻ•āϰāĻž āĻšāĻšā§āϛ⧇)āĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ–āĻžāύ⧇ āĻāĻ•āϟāĻŋ āĻŸā§āϰāĻŋāĻ• āφāϛ⧇āĨ¤ āϚāϞ⧁āύ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋ (Recursion Tree) āĻĻāĻŋā§Ÿā§‡ āĻŦāĻŋāώ⧟āϟāĻŋ āϏāĻšāĻœā§‡ āĻŦ⧁āĻāĻŋ:

ā§§. āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϧāĻžāĻĒ⧇ ⧍ āĻ­āĻžāϗ⧇ āĻ­āĻžāĻ— āĻšāĻšā§āϛ⧇ āĻāĻŦāĻ‚ ⧍ āĻŦāĻžāϰ āύāĻŋāĻœā§‡āϕ⧇ āĻ•āϞ āĻ•āϰāϛ⧇āĨ¤

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ

āφāĻŽāϰāĻž āϝāĻĻāĻŋ āĻŽā§‹āϟ āĻ•āϞ⧇āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻšāĻŋāϏ⧇āĻŦ āĻ•āϰāĻŋ: \(Total\ Calls = 1 + 2 + 4 + 8 + \dots + n\)

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻœā§āϝāĻžāĻŽāĻŋāϤāĻŋāĻ• āϧāĻžāϰāĻž (Geometric Series)āĨ¤ āĻāχ āϧāĻžāϰāĻžāϰ āϝ⧋āĻ—āĻĢāϞ āĻšāϞ⧋ āĻĒā§āϰāĻžā§Ÿ $2n - 1$āĨ¤

āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇ āφāĻŽāϰāĻž āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ (āϝ⧇āĻŽāύ ⧍) āĻŦāĻžāĻĻ āĻĻ⧇āχ, āϤāĻžāχ āĻāϟāĻŋ āĻĻāĻžāρ⧜āĻžā§Ÿ $O(n)$āĨ¤

ā§Š. āĻŽāĻžāĻ¸ā§āϟāĻžāϰ āĻĨāĻŋāĻ“āϰ⧇āĻŽ (Master Theorem) āĻĒā§āĻ°ā§Ÿā§‹āĻ—

āĻ…ā§āϝāĻžāĻĄāĻ­āĻžāĻ¨ā§āϏāĻĄ āϞ⧇āϭ⧇āϞ⧇ āĻāχ āϧāϰāύ⧇āϰ āχāϕ⧁āϝāĻŧ⧇āĻļāύ āϏāϞāĻ­ āĻ•āϰāϤ⧇ āĻŽāĻžāĻ¸ā§āϟāĻžāϰ āĻĨāĻŋāĻ“āϰ⧇āĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšā§Ÿ:\(T(n) = 2T(n/2) + O(1)\)

\[T(n) = 2T(n/2) + O(1)\]

āĻāĻ–āĻžāύ⧇:

āϝ⧇āĻšā§‡āϤ⧁ $\log_b a = \log_2 2 = 1$ āĻāĻŦāĻ‚ $f(n)$ āĻāϰ āĻĒāĻžāĻ“ā§ŸāĻžāϰ ā§Ļ, āϤāĻžāχ āĻŽāĻžāĻ¸ā§āϟāĻžāϰ āĻĨāĻŋāĻ“āϰ⧇āĻŽā§‡āϰ ā§§āĻŽ āϕ⧇āϏ āĻ…āύ⧁āϝāĻžā§Ÿā§€ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšā§Ÿ $O(n^{\log_2 2}) = O(n^1) = O(n)$āĨ¤


for(int i=1; i<=n; i++){
    for(int j=1; j<=i*i; j++){
            sum++;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^3)$āĨ¤

ā§§. āϞ⧁āĻĒ⧇āϰ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻŦ⧇āϰ āĻ•āϰāĻž

āĻāĻ–āĻžāύ⧇ āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒāϟāĻŋ ($j$) āĻŦāĻžāχāϰ⧇āϰ āϞ⧁āĻĒ⧇āϰ āχāύāĻĄā§‡āĻ•ā§āϏ $i$ āĻāϰ āĻ“āĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰāϛ⧇āĨ¤

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ (Sum of Squares)

āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻŦ⧇āϰ āĻ•āϰāϤ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻāχ āĻŦāĻ°ā§āϗ⧇āϰ āϧāĻžāϰāĻžāϟāĻŋ (Series of Squares) āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻšāĻŦ⧇:

\[Total\ Work = 1^2 + 2^2 + 3^2 + ... + n^2\]

āφāĻŽāϰāĻž āϜāĻžāύāĻŋ, āĻĒā§āϰāĻĨāĻŽ $n$ āϏāĻ‚āĻ–ā§āϝāĻ• āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ• āϏāĻ‚āĻ–ā§āϝāĻžāϰ āĻŦāĻ°ā§āϗ⧇āϰ āϝ⧋āĻ—āĻĢāϞ⧇āϰ āϏ⧂āĻ¤ā§āϰ āĻšāϞ⧋:\(Sum = \frac{n(n+1)(2n+1)}{6}\)

ā§Š. āϕ⧇āύ āĻāϟāĻŋ $O(n^3)$?

āφāĻŽāϰāĻž āϝāĻĻāĻŋ āωāĻĒāϰ⧇āϰ āχāĻ•ā§ā§Ÿā§‡āĻļāύāϟāĻŋāϕ⧇ āϗ⧁āĻŖ āĻ•āϰāĻŋ:

\[Sum = \frac{(n^2 + n)(2n + 1)}{6} = \frac{2n^3 + 3n^2 + n}{6}\]

āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇āϰ āύāĻŋ⧟āĻŽ āĻ…āύ⧁āϝāĻžā§Ÿā§€:

āĻĒā§āϰ⧋-āϟāĻŋāĻĒ:

āϝāĻĻāĻŋ āφāĻĒāύāĻžāϰ āĻŦāĻžāχāϰ⧇āϰ āϞ⧁āĻĒ $n$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϚāϞ⧇ āĻāĻŦāĻ‚ āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒ $i^k$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϚāϞ⧇, āϤāĻŦ⧇ āϤāĻžāϰ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖāϤ $O(n^{k+1})$ āĻšā§ŸāĨ¤ āĻāĻ–āĻžāύ⧇ $k=2$ āĻ›āĻŋāϞ, āϤāĻžāχ āωāĻ¤ā§āϤāϰ āĻšā§Ÿā§‡āϛ⧇ $O(n^{2+1}) = O(n^3)$āĨ¤


for(int i=1; i<=n; i=i*3){
    for(int j=1; j<=n; j++){
            sum++;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n \log_3 n)$, āϝāĻž āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇ āϏāĻžāϧāĻžāϰāĻŖāϤ $O(n \log n)$ āĻšāĻŋāϏ⧇āĻŦ⧇ āϞ⧇āĻ–āĻž āĻšā§ŸāĨ¤

ā§§. āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

⧍. āĻŽā§‹āϟ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ

āĻāĻ•āϟāĻŋ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ⧇ āφāϰ⧇āĻ•āϟāĻŋ āϞ⧁āĻĒ āĻĨāĻžāĻ•āϞ⧇ āφāĻŽāϰāĻž āϤāĻžāĻĻ⧇āϰ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āϗ⧁āĻŖ āĻ•āϰāĻŋ:

\[Total\ Time = (\text{Outer Loop}) \times (\text{Inner Loop})\] \[Total\ Time = \log_3 n \times n = O(n \log_3 n)\]

āϝ⧇āĻšā§‡āϤ⧁ āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇ āϞāĻ—āĻžāϰāĻŋāĻĻāĻŽā§‡āϰ āĻŦ⧇āϏ (⧍, ā§Š āĻŦāĻž ā§§ā§Ļ) āϖ⧁āĻŦ āĻāĻ•āϟāĻž āĻĒā§āϰāĻ­āĻžāĻŦ āĻĢ⧇āϞ⧇ āύāĻž (āϏāĻŦāϗ⧁āϞ⧋āχ āĻāϕ⧇ āĻ…āĻĒāϰ⧇āϰ āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āĻŽāĻžāĻ˛ā§āϟāĻŋāĻĒāϞ), āϤāĻžāχ āĻāϕ⧇ āϏāĻžāϧāĻžāϰāĻŖāĻ­āĻžāĻŦ⧇ $O(n \log n)$ āĻŦāϞāĻž āĻšā§ŸāĨ¤ ___

int i=0;
while(i<n){
    int j=n;
    while(j>0){
        j = j/2;
    }
    i++
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n \log n)$āĨ¤

ā§§. āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

⧍. āĻŽā§‹āϟ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ

āϝ⧇āĻšā§‡āϤ⧁ āĻāĻ•āϟāĻŋ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ⧇ āφāϰ⧇āĻ•āϟāĻŋ āϞ⧁āĻĒ āφāϛ⧇, āϤāĻžāχ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻšāĻŦ⧇ āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āϗ⧁āĻŖāĻĢāϞ: \(Total\ Time = (Outer\ Loop\ Iterations) \times (Inner\ Loop\ Iterations)\)

\[Total\ Time = n \times \log n = O(n \log n)\]
HashMap <Integer, List<Integer>>map=new HashMap<>();
for(int i=0; i<n; i++){
  List<Integer> list = new ArrayList<>();
  for(int j=0; j<n; j++){
    list.add(j);
  }
  map.put(i,list);
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^2)$āĨ¤

āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

ā§§. āĻŦāĻžāχāϰ⧇āϰ āĻ—āĻ āύ (HashMap):

āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ HashMap āϤ⧈āϰāĻŋ āĻ•āϰāϛ⧇āύ āϝ⧇āĻ–āĻžāύ⧇ $n$ āϟāĻŋ āϕ⧀ (Key) āĻĨāĻžāĻ•āĻŦ⧇āĨ¤ āϏ⧁āϤāϰāĻžāĻ‚, āĻŽā§āϝāĻžāĻĒ⧇āϰ āϕ⧀āϗ⧁āϞ⧋āϰ āϜāĻ¨ā§āϝ āϜāĻžā§ŸāĻ—āĻž āϞāĻžāĻ—āϛ⧇ $O(n)$āĨ¤

⧍. āϭ⧇āϤāϰ⧇āϰ āĻ—āĻ āύ (ArrayLists):

āϞ⧁āĻĒ⧇āϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϧāĻžāĻĒ⧇ (āĻŽā§‹āϟ $n$ āĻŦāĻžāϰ), āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āĻ•āϰ⧇ āύāϤ⧁āύ ArrayList āϤ⧈āϰāĻŋ āĻ•āϰāϛ⧇āύāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϞāĻŋāĻ¸ā§āĻŸā§‡āϰ āϭ⧇āϤāϰ āφāĻŦāĻžāϰ $n$ āϟāĻŋ āĻ•āϰ⧇ āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āϟ āϰāĻžāĻ–āϛ⧇āύāĨ¤

āĻŽā§‹āϟ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāĻŋāϏāĻžāĻŦ:

\[\text{Total Space} = \text{Space for Map Keys} + \text{Space for all List Elements}\] \[\text{Total Space} = O(n) + O(n^2)\]

āĻŦāĻŋāĻ—-āĻ“ ($O$) āύ⧋āĻŸā§‡āĻļāύ⧇āϰ āύāĻŋ⧟āĻŽ āĻ…āύ⧁āϝāĻžā§Ÿā§€, āφāĻŽāϰāĻž āĻŦ⧜ āĻĒāĻžāĻ“ā§ŸāĻžāϰāϟāĻŋ āϰāĻžāĻ–āĻŋāĨ¤ āϤāĻžāχ āĻĢāĻžāχāύāĻžāϞ āϰ⧇āϜāĻžāĻ˛ā§āϟ āĻšāϞ⧋ $O(n^2)$āĨ¤

ā§Š. āĻāĻ•āϟāĻŋ āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ (Graph Representation):

āĻāχ āϧāϰāύ⧇āϰ āĻĄā§‡āϟāĻž āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ āϏāĻžāϧāĻžāϰāĻŖāϤ āĻ—ā§āϰāĻžāĻĢ āĻĨāĻŋāĻ“āϰāĻŋāϤ⧇ Adjacency List āϤ⧈āϰāĻŋāϰ āϏāĻŽā§Ÿ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšā§ŸāĨ¤ āϝāĻĻāĻŋ āĻāĻ•āϟāĻŋ āĻ—ā§āϰāĻžāĻĢ⧇āϰ $n$ āϟāĻŋ āύ⧋āĻĄ āĻĨāĻžāϕ⧇ āĻāĻŦāĻ‚ āĻĒā§āϰāϤāĻŋāϟāĻŋ āύ⧋āĻĄ āĻŦāĻžāĻ•āĻŋ āϏāĻŦ āύ⧋āĻĄā§‡āϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāύ⧇āĻ•ā§āĻŸā§‡āĻĄ āĻĨāĻžāϕ⧇ (Complete Graph), āϤāĻŦ⧇ āϏ⧇āϟāĻŋāϰ āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻ–āϰāϚ āĻšāĻŦ⧇ $O(n^2)$āĨ¤


for(int i=1; i*i<=n; i++){
    print(i);
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(\sqrt{n})$ (Square Root of $n$)āĨ¤

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āĻ¸ā§āĻŽāĻžāĻ°ā§āϟ āϞ⧁āĻĒ āĻ•āĻ¨ā§āĻĄāĻŋāĻļāύ, āϝāĻž āφāĻŽāϰāĻž āϏāĻžāϧāĻžāϰāĻŖāϤ āϕ⧋āύ⧋ āϏāĻ‚āĻ–ā§āϝāĻžāϰ Primality Testing (āϏāĻ‚āĻ–ā§āϝāĻžāϟāĻŋ āĻŽā§ŒāϞāĻŋāĻ• āĻ•āĻŋ āύāĻž) āĻŦāĻž Divisors (āĻ‰ā§ŽāĻĒāĻžāĻĻāĻ•) āĻŦ⧇āϰ āĻ•āϰāĻžāϰ āϏāĻŽā§Ÿ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŋāĨ¤ āϚāϞ⧁āύ āĻĻ⧇āĻ–āĻŋ āϕ⧇āύ āĻāϟāĻŋ $\sqrt{n}$ āĻšāϞ⧋āĨ¤

ā§§. āϞ⧁āĻĒ⧇āϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āϞ⧁āĻĒ⧇āϰ āĻļāĻ°ā§āϤāϟāĻŋ āĻšāϞ⧋: $i \times i \le n$āĨ¤

āĻāϕ⧇ āĻ…āĻ¨ā§āϝāĻ­āĻžāĻŦ⧇ āϞ⧇āĻ–āĻž āϝāĻžā§Ÿ: $i \le \sqrt{n}$āĨ¤

āĻ…āĻ°ā§āĻĨāĻžā§Ž, āϞ⧁āĻĒāϟāĻŋ ā§§ āĻĨ⧇āϕ⧇ āĻļ⧁āϰ⧁ āĻšā§Ÿā§‡ āϤāϤāĻ•ā§āώāĻŖ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϚāϞāĻŦ⧇ āϝāϤāĻ•ā§āώāĻŖ $i$ āĻāϰ āĻŽāĻžāύ $\sqrt{n}$ āĻāϰ āϏāĻŽāĻžāύ āĻŦāĻž āϛ⧋āϟ āĻĨāĻžāϕ⧇āĨ¤

āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ

āϞ⧁āĻĒāϟāĻŋ āϝāĻĻāĻŋ $k$ āĻŦāĻžāϰ āϚāϞ⧇, āϤāĻŦ⧇ āĻļāĻ°ā§āϤ āĻ…āύ⧁āϝāĻžā§Ÿā§€:

\[k^2 \le n\] \[k \le \sqrt{n}\]

āϏ⧁āϤāϰāĻžāĻ‚, āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻŦāĻž āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(\sqrt{n})$āĨ¤

āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋāϰ āϤ⧁āϞāύāĻž:

$O(\sqrt{n})$ āϞāĻŋāύāĻŋ⧟āĻžāϰ āϟāĻžāχāĻŽ ($O(n)$) āĻāϰ āĻšā§‡ā§Ÿā§‡ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āĻĻā§āϰ⧁āϤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āϞāĻ—āĻžāϰāĻŋāĻĻāĻŽāĻŋāĻ• āϟāĻžāχāĻŽ ($O(\log n)$) āĻāϰ āĻšā§‡ā§Ÿā§‡ āĻ•āĻŋāϛ⧁āϟāĻž āϧ⧀āϰāĨ¤


for(int i=0; i<n; i++){
    for(int j=0; j<n; j++){
        break;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n)$āĨ¤

āϕ⧇āύ āĻāϟāĻŋ $O(n)$?

āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ:

āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āϏāĻ‚āĻ–ā§āϝāĻž = (āĻŦāĻžāχāϰ⧇āϰ āϞ⧁āĻĒ⧇āϰ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ) $\times$ (āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒ⧇āϰ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ)

\[\text{Total Operations} = n \times 1 = n\]

āϤāĻžāχ āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇ āĻāϟāĻŋ $O(n)$āĨ¤


void foo(int n){
    if(n<=1) return;
    foo(n/2);
    for(int i=0; i<n; i++){
        print(i)
    }
    foo(n/2);
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n \log n)$āĨ¤

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āĻ•ā§āϞāĻžāϏāĻŋāĻ• āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āϝāĻž āφāĻŽāϰāĻž āϏāĻžāϧāĻžāϰāĻŖāϤ Merge Sort āĻŦāĻž āĻāχ āϜāĻžāĻ¤ā§€ā§Ÿ Divide and Conquer āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽā§‡ āĻĻ⧇āϖ⧇ āĻĨāĻžāĻ•āĻŋāĨ¤ āϚāϞ⧁āύ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāϰ āĻ—āĻ­ā§€āϰ⧇ āϝāĻžāĻ“ā§ŸāĻž āϝāĻžāĻ•:

ā§§. āϕ⧋āĻĄāϟāĻŋāϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻāχ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻŽā§‚āϞāϤ āϤāĻŋāύāϟāĻŋ āĻ•āĻžāϜ āĻ•āϰāϛ⧇:

āĻāϰ āϰāĻŋāĻ•āĻžāϰ⧇āĻ¨ā§āϏ āϰāĻŋāϞ⧇āĻļāύāϟāĻŋ āĻšāĻŦ⧇:

\[T(n) = 2T(n/2) + n\]

⧍. āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋ (Recursion Tree) āĻĻāĻŋā§Ÿā§‡ āĻŦā§‹āĻāĻž

āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻ•āĻ˛ā§āĻĒāύāĻž āĻ•āϰ⧇āύ āĻāχ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻ›ā§œāĻŋā§Ÿā§‡ āĻĒ⧜āϛ⧇:

āĻĒā§āϰāϤāĻŋāϟāĻŋ āϞ⧇āϭ⧇āϞ⧇ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻ•āĻŋāĻ¨ā§āϤ⧁ $n$ āχ āĻĨāĻžāĻ•āϛ⧇āĨ¤ āĻāĻ–āύ āĻĒā§āϰāĻļā§āύ āĻšāϞ⧋, āĻ•āϤāϗ⧁āϞ⧋ āϞ⧇āϭ⧇āϞ āφāϛ⧇? āϝ⧇āĻšā§‡āϤ⧁ $n$ āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻ…āĻ°ā§āϧ⧇āĻ• āĻšāĻšā§āϛ⧇, āϤāĻžāχ āĻŽā§‹āϟ āϞ⧇āϭ⧇āϞ āφāϛ⧇ $\log_2 n$ āϟāĻŋāĨ¤

ā§Š. āĻŽā§‹āϟ āĻšāĻŋāϏāĻžāĻŦ

\[\text{Total Time} = (\text{Work per level}) \times (\text{Number of levels})\] \[\text{Total Time} = n \times \log_2 n = O(n \log n)\]

ā§Ē. āĻŽāĻžāĻ¸ā§āϟāĻžāϰ āĻĨāĻŋāĻ“āϰ⧇āĻŽ (Master Theorem) āĻĒā§āĻ°ā§Ÿā§‹āĻ—

āϝāĻĻāĻŋ āφāĻĒāύāĻŋ āϏāϰāĻžāϏāϰāĻŋ āϏ⧂āĻ¤ā§āϰ āĻĻāĻŋā§Ÿā§‡ āĻ•āϰāϤ⧇ āϚāĻžāύ:

\[T(n) = aT(n/b) + f(n)\]

āĻāĻ–āĻžāύ⧇ $a = 2$, $b = 2$, āĻāĻŦāĻ‚ $f(n) = n^1$āĨ¤

āϝ⧇āĻšā§‡āϤ⧁ $\log_b a = \log_2 2 = 1$, āϝāĻž $f(n)$-āĻāϰ āĻĒāĻžāĻ“ā§ŸāĻžāϰ⧇āϰ āϏāĻŽāĻžāύ, āĻāϟāĻŋ āĻŽāĻžāĻ¸ā§āϟāĻžāϰ āĻĨāĻŋāĻ“āϰ⧇āĻŽā§‡āϰ ⧍⧟ āϕ⧇āϏāĨ¤ āϤāĻžāχ āϰ⧇āϜāĻžāĻ˛ā§āϟ āĻšāĻŦ⧇ $O(n^1 \log n)$āĨ¤


for(int i=0; i<n; i++){
    for(int j=0; j<n; i++){
        for(int k=j; k<n; k++){
            sum++;
        }
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^3)$āĨ¤

ā§§. āϞ⧁āĻĒ⧇āϰ āĻ—āĻ āύ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻāχ āϭ⧇āϤāϰ⧇āϰ āĻĻ⧁āϟāĻŋ āϞ⧁āĻĒ⧇āϰ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻšāϞ⧋ āĻāĻ•āϟāĻŋ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āϧāĻžāϰāĻž (Arithmetic Progression):

\[n + (n-1) + (n-2) + \dots + 1 = \frac{n(n+1)}{2}\]

āĻāϟāĻŋ āĻŽā§‚āϞāϤ $O(n^2)$ āĻāϰ āϏāĻŽāĻžāύāĨ¤

⧍. āĻŽā§‹āϟ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāĻŋāϏāĻžāĻŦ

āĻāĻ–āύ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ āφāϛ⧇:

āϏāĻŦ āĻŽāĻŋāϞāĻŋā§Ÿā§‡ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ:

\[\text{Total Operations} = n \times \frac{n^2+n}{2} = \frac{n^3+n^2}{2}\]

āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇āϰ āύāĻŋ⧟āĻŽ āĻ…āύ⧁āϝāĻžā§Ÿā§€, āφāĻŽāϰāĻž āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ ($1/2$) āĻāĻŦāĻ‚ āϛ⧋āϟ āϘāĻžāϤ ($n^2$) āĻŦāĻžāĻĻ āĻĻāĻŋā§Ÿā§‡ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āϏāĻŦāĻĨ⧇āϕ⧇ āĻŦ⧜ āϘāĻžāϤāϟāĻŋ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰāĻŋāĨ¤ āϤāĻžāχ āϰ⧇āϜāĻžāĻ˛ā§āϟ āĻĻāĻžāρ⧜āĻžā§Ÿ $O(n^3)$āĨ¤


void solve(int n){
    if(n <=1) return;
    for(int i=0; i<n; i++){
        print(i)
    }
    solve(n/3)
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n)$āĨ¤

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻĢāĻžāĻ‚āĻļāύ āϝāĻžāϰ āϭ⧇āϤāϰ⧇ āĻāĻ•āϟāĻŋ āϞ⧁āĻĒ āĻ°ā§Ÿā§‡āϛ⧇āĨ¤ āĻāϟāĻŋ āϕ⧇āύ $O(n)$ āĻšāϞ⧋, āϤāĻž āĻŦ⧁āĻāϤ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āϞ⧇āϭ⧇āϞ⧇ āĻ•āϤāϟ⧁āϕ⧁ āĻ•āĻžāϜ āĻšāĻšā§āϛ⧇ āϤāĻž āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤

ā§§. āĻ•āĻžāĻœā§‡āϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ (Step-by-Step)

āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϧāĻžāĻĒ⧇ āύāĻŋāĻšā§‡āϰ āĻ•āĻžāϜāϗ⧁āϞ⧋ āĻ•āϰāϛ⧇:

āϚāϞ⧁āύ āĻĻ⧇āĻ–āĻŋ āĻŽā§‹āϟ āĻ•āϤāĻŦāĻžāϰ print āĻšāĻšā§āϛ⧇:

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ

āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻšāϞ⧋ āĻāĻ•āϟāĻŋ āĻ…āϏ⧀āĻŽ āϗ⧁āĻŖā§‹āĻ¤ā§āϤāϰ āϧāĻžāϰāĻž (Infinite Geometric Series) āĻāϰ āϝ⧋āĻ—āĻĢāϞ (āϤāĻžāĻ¤ā§āĻ¤ā§āĻŦāĻŋāĻ•āĻ­āĻžāĻŦ⧇):

\[\text{Total Work} = n + \frac{n}{3} + \frac{n}{9} + \frac{n}{27} + \dots\]

āφāĻŽāϰāĻž āϝāĻĻāĻŋ $n$ āĻ•āĻŽāύ āύ⧇āχ:

\[\text{Total Work} = n \left( 1 + \frac{1}{3} + \frac{1}{9} + \frac{1}{27} + \dots \right)\]

āĻāχ āϧāĻžāϰāĻžāϰ āϝ⧋āĻ—āĻĢāϞ⧇āϰ āϏ⧂āĻ¤ā§āϰ $\frac{a}{1-r}$ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϞ⧇ āφāĻŽāϰāĻž āĻĒāĻžāχ:

\[\text{Total Work} = n \times \left( \frac{1}{1 - 1/3} \right) = n \times \frac{3}{2} = 1.5n\]

ā§Š. āĻŦāĻŋāĻ—-āĻ“ ($O$) āĻĢāϞāĻžāĻĢāϞ

āϝ⧇āĻšā§‡āϤ⧁ $1.5$ āĻāĻ•āϟāĻŋ āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āĻŦāĻž āĻ§ā§āϰ⧁āĻŦāĻ•, āϤāĻžāχ āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇ āφāĻŽāϰāĻž āĻāϕ⧇ āĻŦāĻžāĻĻ āĻĻ⧇āχāĨ¤ āĻĢāϞ⧇ āĻšā§‚ā§œāĻžāĻ¨ā§āϤ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻĻāĻžāρ⧜āĻžā§Ÿ: $O(n)$

āϏāĻšāϜ āĻŸā§‡āĻ•āύāĻŋāĻ•:

āϝāĻĻāĻŋ āĻĻ⧇āϖ⧇āύ āĻāĻ•āϟāĻŋ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻĢāĻžāĻ‚āĻļāύ⧇ āχāύāĻĒ⧁āϟ āĻ­āĻžāĻ— āĻšāĻšā§āϛ⧇ (āϝ⧇āĻŽāύ $n/2, n/3$) āĻāĻŦāĻ‚ āϏ⧇āχ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āϭ⧇āϤāϰ⧇ āĻāĻ•āϟāĻŋ āϞāĻŋāύāĻŋ⧟āĻžāϰ āϞ⧁āĻĒ ($O(n)$) āφāϛ⧇ āϝāĻž āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻ•āĻŽāϛ⧇, āϤāĻŦ⧇ āϏ⧇āχ āĻĒ⧁āϰ⧋ āϕ⧋āĻĄā§‡āϰ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖāϤ āϞāĻŋāύāĻŋ⧟āĻžāϰ āĻŦāĻž $O(n)$ āχ āĻĨāĻžāϕ⧇āĨ¤ āĻ•āĻžāϰāĻŖ āĻĒā§āϰāĻĨāĻŽ āĻ•āϞ⧇āϰ āĻ•āĻžāϜāχ āϏāĻŦāĻĨ⧇āϕ⧇ āĻŦ⧇āĻļāĻŋ, āĻĒāϰ⧇āϰ āĻ•āϞāϗ⧁āϞ⧋āϰ āĻ•āĻžāϜ āĻāϤāχ āĻĻā§āϰ⧁āϤ āĻ•āĻŽā§‡ āϝ⧇ āϏ⧇āϗ⧁āϞ⧋ āϝ⧋āĻ— āĻ•āϰāϞ⧇āĻ“ āĻĒā§āϰāĻĨāĻŽ āĻ•āϞ⧇āϰ āĻĻā§āĻŦāĻŋāϗ⧁āĻŖ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āύāĻžāĨ¤


for(int i=0; i<n; i++){
    for(int j=0; j<n; i++){
        c[i][j]=0;
        for(int k=0; k<n; k++){
            c[i][j]+=a[i][k]*b[k][j]
        }
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^3)$āĨ¤

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āϏ⧁āĻĒāϰāĻŋāϚāĻŋāϤ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽâ€”Matrix Multiplication (āĻŽā§āϝāĻžāĻŸā§āϰāĻŋāĻ•ā§āϏ āϗ⧁āĻŖāĻĢāϞ)āĨ¤ āϚāϞ⧁āύ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ āĻ•āϰ⧇ āĻĻ⧇āĻ–āĻŋ āϕ⧇āύ āĻāϟāĻŋ $O(n^3)$ āĻšāϞ⧋:

ā§§. āϞ⧁āĻĒ⧇āϰ āĻ—āĻ āύ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻāχ āϕ⧋āĻĄāϟāĻŋāϤ⧇ āϤāĻŋāύāϟāĻŋ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ (āĻāĻ•āϟāĻŋāϰ āϭ⧇āϤāϰ āφāϰ⧇āĻ•āϟāĻŋ) āϞ⧁āĻĒ āĻ°ā§Ÿā§‡āϛ⧇:

  1. āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āĻŦāĻžāχāϰ⧇āϰ āϞ⧁āĻĒ (i): āĻāϟāĻŋ $0$ āĻĨ⧇āϕ⧇ $n-1$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϚāϞ⧇, āĻ…āĻ°ā§āĻĨāĻžā§Ž āĻāϟāĻŋ āĻŽā§‹āϟ $n$ āĻŦāĻžāϰ āĻ˜ā§‹āϰ⧇āĨ¤ āĻāϟāĻŋ āϰ⧇āϜāĻžāĻ˛ā§āϟ āĻŽā§āϝāĻžāĻŸā§āϰāĻŋāĻ•ā§āϏ⧇āϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ ‘āĻ°ā§‹â€™ (row) āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰ⧇āĨ¤
  2. āĻŽāĻžāĻāĻ–āĻžāύ⧇āϰ āϞ⧁āĻĒ (j): āĻāϟāĻŋāĻ“ $0$ āĻĨ⧇āϕ⧇ $n-1$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϚāϞ⧇, āĻ…āĻ°ā§āĻĨāĻžā§Ž āĻāϟāĻŋāĻ“ āĻŽā§‹āϟ $n$ āĻŦāĻžāϰ āĻ˜ā§‹āϰ⧇āĨ¤ āĻāϟāĻŋ āĻĒā§āϰāϤāĻŋāϟāĻŋ ‘āĻ•āϞāĻžāĻŽâ€™ (column) āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰ⧇āĨ¤
  3. āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒ (k): āĻāϟāĻŋāĻ“ $0$ āĻĨ⧇āϕ⧇ $n-1$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϚāϞ⧇, āĻ…āĻ°ā§āĻĨāĻžā§Ž āĻāϟāĻŋāĻ“ āĻŽā§‹āϟ $n$ āĻŦāĻžāϰ āĻ˜ā§‹āϰ⧇āĨ¤ āĻāϟāĻŋ āĻŽā§‚āϞāϤ āĻĄāϟ āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ (dot product) āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āĻŸā§‡āϰ āϗ⧁āĻŖ āĻāĻŦāĻ‚ āϝ⧋āĻ— āϏāĻŽā§āĻĒāĻ¨ā§āύ āĻ•āϰ⧇āĨ¤

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ

āϝ⧇āĻšā§‡āϤ⧁ āϞ⧁āĻĒāϗ⧁āϞ⧋ āĻāϕ⧇ āĻ…āĻĒāϰ⧇āϰ āϭ⧇āϤāϰ⧇ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύ āĻ•āϰāϛ⧇, āϤāĻžāχ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻšāĻŦ⧇ āϞ⧁āĻĒāϗ⧁āϞ⧋āϰ āϗ⧁āĻŖāĻĢāϞ:

\[\text{Total Operations} = n \times n \times n = n^3\]

āĻŦāĻŋāĻ—-āĻ“ āύ⧋āĻŸā§‡āĻļāύ⧇ āĻāϕ⧇ āφāĻŽāϰāĻž āϞāĻŋāĻ–āĻŋ $O(n^3)$āĨ¤

ā§Š. āĻ­āĻŋāĻœā§āϝ⧁āϝāĻŧāĻžāϞāĻžāχāĻœā§‡āĻļāύ

āĻ•āĻ˛ā§āĻĒāύāĻž āĻ•āϰ⧁āύ āĻāĻ•āϟāĻŋ āϘāύāĻ• (Cube) āϝāĻžāϰ āĻĻ⧈āĻ°ā§āĻ˜ā§āϝ, āĻĒā§āϰāĻ¸ā§āĻĨ āĻāĻŦāĻ‚ āωāĻšā§āϚāϤāĻž āĻĒā§āϰāϤāĻŋāϟāĻŋāχ $n$āĨ¤ āĻŽā§āϝāĻžāĻŸā§āϰāĻŋāĻ•ā§āϏ āϗ⧁āϪ⧇āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϏ⧇āϞ⧇āϰ āĻŽāĻžāύ āĻŦ⧇āϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āφāĻŽāĻžāĻĻ⧇āϰ āĻĒ⧁āϰ⧋ āĻāĻ•āϟāĻŋ āϰ⧋ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āĻ•āϞāĻžāĻŽā§‡āϰ āĻ“āĻĒāϰ āĻĻāĻŋā§Ÿā§‡ āϝ⧇āϤ⧇ āĻšā§Ÿ, āϝāĻž āĻāχ āĻ•āĻŋāωāĻŦāĻŋāĻ• āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤


int power(int base, int exp){
    if (exp == 0 ) return 1;
    if(exp % 2 ==0)
        return power(base * base, exp / 2 )
    else
        return base * power (base, exp - 1)
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(\log \text{exp})$āĨ¤

ā§§. āϕ⧇āύ āĻāϟāĻŋ $O(\log \text{exp})$?

āĻāχ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋāϰ āĻŽā§‚āϞ āĻļāĻ•ā§āϤāĻŋ āϞ⧁āĻ•āĻŋā§Ÿā§‡ āφāϛ⧇ exp / 2 āĻ…āĻ‚āĻļāϟāĻŋāϤ⧇āĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϧāĻžāĻĒ⧇ āφāĻŽāϰāĻž āĻāĻ•ā§āϏāĻĒā§‹āύ⧇āĻ¨ā§āϟ āĻŦāĻž āĻĒāĻžāĻ“ā§ŸāĻžāϰāϕ⧇ āĻĻ⧁āχ āĻ­āĻžāϗ⧇ āĻ­āĻžāĻ— āĻ•āϰ⧇ āĻĻāĻŋāĻšā§āĻ›āĻŋāĨ¤

āϝ⧇āĻšā§‡āϤ⧁ āφāĻŽāϰāĻž āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āϧāĻžāĻĒ⧇ āχāύāĻĒ⧁āϟāϕ⧇ ⧍ āĻĻāĻŋā§Ÿā§‡ āĻ­āĻžāĻ— āĻ•āϰāĻ›āĻŋ, āϤāĻžāχ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ Logarithmic āĻĒā§āϰāϏ⧇āϏāĨ¤

⧍. āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāϪ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻĻ⧇āĻ–āĻž āϝāĻžāĻ•:

āϧāϰāĻž āϝāĻžāĻ• āφāĻŽāϰāĻž $2^{10}$ āĻŦ⧇āϰ āĻ•āϰāϤ⧇ āϚāĻžāχ:

āĻāĻ–āĻžāύ⧇ exp = 10 āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻŽāĻžāĻ¤ā§āϰ ā§ŦāϟāĻŋ āϧāĻžāĻĒ⧇ āĻ•āĻžāϜ āĻļ⧇āώ āĻ•āϰ⧇āϛ⧇āĨ¤ āχāύāĻĒ⧁āϟ āϝāϤ āĻŦāĻžā§œāĻŦ⧇, āĻāχ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ⧇āϰ āĻŽāĻžāĻšāĻžāĻ¤ā§āĻŽā§āϝ āϤāϤ āĻŦāĻžā§œāĻŦ⧇āĨ¤

ā§Š. āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ:

āĻāĻ–āĻžāύ⧇ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤ āϝ⧇āĻšā§‡āϤ⧁ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻ¸ā§āĻŸā§āϝāĻžāϕ⧇āϰ āĻ—āĻ­ā§€āϰāϤāĻžāĻ“ āϞāĻ—āĻžāϰāĻŋāĻĻāĻŽāĻŋāĻ•āĻ­āĻžāĻŦ⧇ āĻŦāĻžā§œā§‡, āϤāĻžāχ āĻāϰ āĻ¸ā§āĻĒ⧇āϏ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(\log \text{exp})$āĨ¤


for(int i=0; i<n; i++){
    int x=i;
    while(x>0){
        x/=10;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n \log_{10} n)$āĨ¤

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āχāĻ¨ā§āϟāĻžāϰ⧇āĻ¸ā§āϟāĻŋāĻ‚ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āϝ⧇āĻ–āĻžāύ⧇ āĻŦāĻžāχāϰ⧇āϰ āϞ⧁āĻĒāϟāĻŋ āϞāĻŋāύāĻŋ⧟āĻžāϰ āĻšāϞ⧇āĻ“ āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒāϟāĻŋ āχāύāĻĒ⧁āĻŸā§‡āϰ āĻŽāĻžāύ⧇āϰ āĻ“āĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰāϛ⧇āĨ¤ āϚāϞ⧁āύ āϧāĻžāĻĒ⧇ āϧāĻžāĻĒ⧇ āĻāϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ āĻĻ⧇āĻ–āĻŋ:

ā§§. āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

⧍. āĻŽā§‹āϟ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāĻŋāϏāĻžāĻŦ

āĻāĻ–āĻžāύ⧇ āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻšāĻŦ⧇ āĻĒā§āϰāϤāĻŋāϟāĻŋ $i$-āĻāϰ āϜāĻ¨ā§āϝ āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒ⧇āϰ āĻ•āĻžāĻœā§‡āϰ āϝ⧋āĻ—āĻĢāϞ:

\[\text{Total Work} = \sum_{i=1}^{n} \log_{10} i\]

āϞāĻ—āĻžāϰāĻŋāĻĻāĻŽā§‡āϰ āϧāĻ°ā§āĻŽ āĻ…āύ⧁āϝāĻžā§Ÿā§€, $\log 1 + \log 2 + \dots + \log n = \log(n!)$āĨ¤ āĻ¸ā§āϟāĻžāĻ°ā§āϞāĻŋāĻ‚ā§Ÿā§‡āϰ āĻ…ā§āϝāĻžāĻĒā§āϰ⧋āĻ•ā§āϏāĻŋāĻŽā§‡āĻļāύ (Stirling’s Approximation) āĻ…āύ⧁āϝāĻžā§Ÿā§€, $\log(n!)$ āĻāϰ āĻŽāĻžāύ āĻĒā§āϰāĻžā§Ÿ $n \log n$ āĻāϰ āϏāĻŽāĻžāύāĨ¤

āϤāĻžāχ āĻŦāĻŋāĻ—-āĻ“ ($O$) āύ⧋āĻŸā§‡āĻļāύ⧇ āφāĻŽāϰāĻž āĻĒāĻžāχ: $O(n \log_{10} n)$

āϏāĻšāϜāĻ­āĻžāĻŦ⧇ āĻŦā§‹āĻāĻžāϰ āωāĻĒāĻžā§Ÿ:

āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒāϟāĻŋ āĻŽā§‚āϞāϤ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻžāϰ āĻĄāĻŋāϜāĻŋāϟ āĻŦāĻž āĻ…āĻ™ā§āĻ• āϏāĻ‚āĻ–ā§āϝāĻž āĻ•āĻžāωāĻ¨ā§āϟ āĻ•āϰāϛ⧇āĨ¤ āϝ⧇āĻšā§‡āϤ⧁ $n$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻžāϰ āĻ—ā§œ āĻ…āĻ™ā§āĻ• āϏāĻ‚āĻ–ā§āϝāĻž āĻĒā§āϰāĻžā§Ÿ $\log_{10} n$, āϤāĻžāχ āĻĒ⧁āϰ⧋ āĻ•āĻžāϜāϟāĻŋ āĻ•āϰāϤ⧇ $n \times \log_{10} n$ āϏāĻŽā§Ÿ āϞāĻžāĻ—āϛ⧇āĨ¤


boolean isPrime(int n){
    if (n<2) return false;
    for(int i=2; i*i <=n; i++){
        if(n%i==0) return false;
    }
    return true;
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(\sqrt{n})$āĨ¤

ā§§. āϕ⧇āύ āĻāϟāĻŋ $O(\sqrt{n})$?

āϞ⧁āĻĒ⧇āϰ āĻ•āĻ¨ā§āĻĄāĻŋāĻļāύāϟāĻŋ āĻ–ā§‡ā§ŸāĻžāϞ āĻ•āϰ⧁āύ: i * i <= nāĨ¤ āĻāϕ⧇ āϏāĻšāϜ āĻŦā§€āϜāĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āύāĻŋ⧟āĻŽā§‡ āϞāĻŋāĻ–āϞ⧇ āĻĻāĻžāρ⧜āĻžā§Ÿ:

\[i \leq \sqrt{n}\]

āĻ…āĻ°ā§āĻĨāĻžā§Ž, āϞ⧁āĻĒāϟāĻŋ $2$ āĻĨ⧇āϕ⧇ āĻļ⧁āϰ⧁ āĻšā§Ÿā§‡ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ $\sqrt{n}$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϚāϞāĻŦ⧇āĨ¤ āϝ⧇āĻšā§‡āϤ⧁ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϤāϰ⧇āϰ āĻ•āĻžāϜāϗ⧁āϞ⧋ (āĻ­āĻžāĻ—āĻļ⧇āώ āĻšā§‡āĻ• āĻ•āϰāĻž) āĻ§ā§āϰ⧁āĻŦāĻ• āϏāĻŽā§Ÿā§‡āϰ āĻ•āĻžāϜ āĻŦāĻž $O(1)$, āϤāĻžāχ āĻĒ⧁āϰ⧋ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋāϰ āϏāĻŽā§Ÿ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰāϛ⧇ āϞ⧁āĻĒāϟāĻŋ āĻ•āϤāĻŦāĻžāϰ āϘ⧁āϰāϛ⧇ āϤāĻžāϰ āĻ“āĻĒāϰāĨ¤

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āϝ⧁āĻ•ā§āϤāĻŋ (āϕ⧇āύ $\sqrt{n}$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻĻ⧇āĻ–āϞ⧇āχ āĻšā§Ÿ?)

āϝāĻĻāĻŋ $n$ āĻāĻ•āϟāĻŋ āϝ⧌āĻ—āĻŋāĻ• āϏāĻ‚āĻ–ā§āϝāĻž āĻšā§Ÿ, āϤāĻŦ⧇ āϤāĻžāϰ āĻ…āĻ¨ā§āϤāϤ āĻāĻ•āϟāĻŋ āĻ‰ā§ŽāĻĒāĻžāĻĻāĻ• (factor) $a$ āĻĨāĻžāĻ•āĻŦ⧇ āϝāĻž $1 < a \leq \sqrt{n}$ āĻļāĻ°ā§āϤāϟāĻŋ āĻŽā§‡āύ⧇ āϚāϞāĻŦ⧇āĨ¤

ā§Š. āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ:

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āĻĒāϰāĻŋāϚāĻŋāϤ āĻŦā§āϝāĻžāĻ•āĻŸā§āĻ°ā§āϝāĻžāĻ•āĻŋāĻ‚ (Backtracking) āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ, āϝāĻž āĻĻāĻŋā§Ÿā§‡ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϰ⧇āϰ āϏāĻŦ āϧāϰāύ⧇āϰ āĻĒāĻžāϰāĻŽā§āĻŸā§‡āĻļāύ (Permutation) āĻŦāĻž āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ āĻŦ⧇āϰ āĻ•āϰāĻž āĻšā§ŸāĨ¤ āϚāϞ⧁āύ āĻĻ⧇āĻ–āĻŋ āϕ⧇āύ āĻāϰ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻāϤ āĻŦ⧇āĻļāĻŋāĨ¤

ā§§. āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϰ⧇āϰ āϏāĻžāχāϜ āϝāĻĻāĻŋ $n$ āĻšā§Ÿ, āϤāĻŦ⧇ āϤāĻžāϰ āĻŽā§‹āϟ āĻĒāĻžāϰāĻŽā§āĻŸā§‡āĻļāύ āϏāĻ‚āĻ–ā§āϝāĻž āĻšā§Ÿ $n!$ (n factorial)āĨ¤

āĻāχ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻĒā§āϰāĻ•ā§āϰāĻŋ⧟āĻžā§Ÿ āĻŽā§‹āϟ āϞāĻŋāĻĢ āύ⧋āĻĄ (Leaf nodes) āĻŦāĻž āĻļ⧇āώ āϧāĻžāĻĒ⧇āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻšāϞ⧋ $n!$āĨ¤ āĻ…āĻ°ā§āĻĨāĻžā§Ž āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻŽā§‹āϟ $n!$ āĻŦāĻžāϰ āĻļ⧇āώ āĻĒāĻ°ā§āϝāĻžā§Ÿā§‡ āĻĒ⧌āρāĻ›āĻžā§ŸāĨ¤

⧍. āĻ•āĻžāĻœā§‡āϰ āĻšāĻŋāϏāĻžāĻŦ

āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻŦ⧇āϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āφāĻŽāĻžāĻĻ⧇āϰ āĻĻ⧁āϟāĻŋ āϜāĻŋāύāĻŋāϏ āĻŽāĻžāĻĨāĻžā§Ÿ āϰāĻžāĻ–āϤ⧇ āĻšāĻŦ⧇:

ā§Š. āĻšā§‚ā§œāĻžāĻ¨ā§āϤ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ

āϝ⧇āĻšā§‡āϤ⧁ āφāĻŽāϰāĻž $n!$ āϏāĻ‚āĻ–ā§āϝāĻ• āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ āϤ⧈āϰāĻŋ āĻ•āϰāĻ›āĻŋ āĻāĻŦāĻ‚ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āĻ•āϰāϤ⧇ $O(n)$ āϏāĻŽā§Ÿ āϞāĻžāĻ—āϛ⧇, āϤāĻžāχ āĻŽā§‹āϟ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻĻāĻžāρ⧜āĻžā§Ÿ:

\[\text{Total Time} = O(n \times n!)\]

ā§Ē. āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ

āϝāĻĻāĻŋ $n=10$ āĻšā§Ÿ:


void merge_sort(int[] arr, int l, int r) {
    if (l >= r) return;
    int mid = (l + r) / 2;
    merge_sort(arr, l, mid);
    merge_sort(arr, mid + 1, r);
    merge(arr, l, mid, r);  // uses O(n) temp array
}

$O(n!)$āĨ¤ āϤāĻŦ⧇ āφāϰāĻ“ āύāĻŋāϖ⧁āρāϤāĻ­āĻžāĻŦ⧇ āĻŦāϞāϞ⧇ āĻāϟāĻŋ $O(n \times n!)$āĨ¤

ā§§. āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻāχ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϰ⧇āϰ āϏāĻŦ āϧāϰāύ⧇āϰ Permutation (āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ) āĻŦ⧇āϰ āĻ•āϰ⧇āĨ¤ āϝāĻĻāĻŋ āĻ…ā§āϝāĻžāϰ⧇āϤ⧇ $n$ āϟāĻŋ āωāĻĒāĻžāĻĻāĻžāύ āĻĨāĻžāϕ⧇, āϤāĻŦ⧇ āĻŽā§‹āϟ āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ āϏāĻ‚āĻ–ā§āϝāĻž āĻšā§Ÿ $n!$ (n factorial)āĨ¤

āĻāχāĻ­āĻžāĻŦ⧇ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύāϟāĻŋ āύāĻŋāĻšā§‡ āύāĻžāĻŽāϤ⧇ āĻĨāĻžāϕ⧇ āϝāϤāĻ•ā§āώāĻŖ āύāĻž āĻāĻ•āϟāĻŋ āĻĒā§‚āĻ°ā§āĻŖ āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ āϤ⧈āϰāĻŋ āĻšā§ŸāĨ¤ āĻāχ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋāϤ⧇ āĻŽā§‹āϟ āϞāĻŋāĻĢ āύ⧋āĻĄ (Leaf nodes) āĻŦāĻž āĻļ⧇āώ āϧāĻžāĻĒ⧇āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻšāϞ⧋ $n!$āĨ¤

⧍. āϕ⧇āύ $O(n \times n!)$?

āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāĻŋāϏāĻžāĻŦ āĻ•āϰāĻžāϰ āϏāĻŽā§Ÿ āĻĻ⧁āϟāĻŋ āĻŦāĻŋāώ⧟ āĻŽāĻžāĻĨāĻžā§Ÿ āϰāĻžāĻ–āϤ⧇ āĻšā§Ÿ:

āϤāĻžāχ āĻŽā§‹āϟ āϏāĻŽā§Ÿ āϞāĻžāϗ⧇: $n! \times n$ āĻ…āĻ°ā§āĻĨāĻžā§Ž $O(n \times n!)$āĨ¤ āĻ…āĻĒāĻļāύ⧇ āϝ⧇āĻšā§‡āϤ⧁ $O(n!)$ āφāϛ⧇, āϤāĻžāχ āĻāϟāĻŋāχ āϏāĻ āĻŋāĻ• āĻ•ā§āϝāĻžāϟāĻžāĻ—āϰāĻŋāĨ¤

ā§Š. āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ

āϝāĻĻāĻŋ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāϰ⧇āϤ⧇ ā§§ā§ĻāϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž āĻĨāĻžāϕ⧇ ($n=10$):


for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j = j + i) {
        for (int k = 1; k <= n; k = k * 2) {
            sum++;
        }
    }
}

int binarySearch(int[] arr, int target, int lo, int hi) {
    if (lo > hi) return -1;
    int mid = (lo + hi) / 2;
    if (arr[mid] == target) return mid;
    if (arr[mid] > target)
        return binarySearch(arr, target, lo, mid - 1);
    return binarySearch(arr, target, mid + 1, hi);
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(\log n)$āĨ¤

āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ•ā§āϞāĻžāϏāĻŋāĻ• Binary Search āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāĨ¤ āϞāĻŋāύāĻŋ⧟āĻžāϰ āϏāĻžāĻ°ā§āĻšā§‡āϰ āĻŽāϤ⧋ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āϟ āĻāϕ⧇ āĻāϕ⧇ āĻšā§‡āĻ• āύāĻž āĻ•āϰ⧇, āĻāϟāĻŋ āĻĒā§āϰāϤāĻŋ āϧāĻžāĻĒ⧇ āϏāĻžāĻ°ā§āϚ āĻāϰāĻŋ⧟āĻž āĻŦāĻž āĻ–ā§‹āρāϜāĻžāϰ āϜāĻžā§ŸāĻ—āĻž āĻ…āĻ°ā§āϧ⧇āĻ• āĻ•āϰ⧇ āĻĢ⧇āϞ⧇āĨ¤

ā§§. āϕ⧇āύ āĻāϟāĻŋ $O(\log n)$?

āĻŦāĻžāχāύāĻžāϰāĻŋ āϏāĻžāĻ°ā§āĻšā§‡āϰ āĻŽā§‚āϞ āĻļāĻ•ā§āϤāĻŋ āĻšāϞ⧋ “Divide and Conquer” āĻŦāĻž āĻ­āĻžāĻ— āĻ•āϰ⧇ āϜ⧟ āĻ•āϰāĻžāϰ āύ⧀āϤāĻŋāĨ¤ āϚāϞ⧁āύ āĻĻ⧇āĻ–āĻŋ āĻāϟāĻŋ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇:

āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ•āĻ­āĻžāĻŦ⧇, āφāĻŽāϰāĻž $n$ āϕ⧇ āĻ•āϤāĻŦāĻžāϰ $2$ āĻĻāĻŋā§Ÿā§‡ āĻ­āĻžāĻ— āĻ•āϰāϞ⧇ $1$ āĻĒāĻžāĻŦā§‹? āωāĻ¤ā§āϤāϰāϟāĻŋ āĻšāϞ⧋ $\log_2 n$

⧍. āϰāĻŋāĻ•āĻžāĻ°ā§āϏāύ āĻŸā§āϰāĻŋ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āϝ⧇āĻšā§‡āϤ⧁ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻĢāĻžāĻ‚āĻļāύ, āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ•āϞ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻ¸ā§āĻŸā§āϝāĻžāĻ• āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ–āĻžāύ⧇ āĻŽāϜāĻžāϰ āĻŦā§āϝāĻžāĻĒāĻžāϰ āĻšāϞ⧋, āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻāĻ•āϟāĻŋ āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻ•āϞ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āĻšā§Ÿ (āĻšā§Ÿ āĻŦāĻžāĻŽ āĻĻāĻŋāϕ⧇, āύāĻžāĻšā§Ÿ āĻĄāĻžāύ āĻĻāĻŋāϕ⧇)āĨ¤ āĻĢāϞ⧇ āĻāϟāĻŋ āĻŽāĻžāĻ°ā§āϜ āϏāĻ°ā§āĻŸā§‡āϰ āĻŽāϤ⧋ āĻŦāĻŋāĻļāĻžāϞ āϕ⧋āύ⧋ āĻŸā§āϰāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰ⧇ āύāĻž, āĻŦāϰāĻ‚ āĻāĻ•āϟāĻŋ āϏ⧋āϜāĻž āϞāĻžāχāύ⧇āϰ āĻŽāϤ⧋ āύāĻŋāĻšā§‡ āύāĻžāĻŽā§‡āĨ¤

ā§Š. āϏ⧇āϰāĻž āĻāĻŦāĻ‚ āĻ–āĻžāϰāĻžāĻĒ āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋ (Best vs Worst Case)


for (int i = 2; i <= n; i++) {
    for (int j = 2; j * j <= i; j++) {
        if (i % j == 0) break;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n\sqrt{n})$ āĻŦāĻž $O(n^{1.5})$āĨ¤

āĻāϟāĻŋ āĻŽā§‚āϞāϤ $2$ āĻĨ⧇āϕ⧇ $n$ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž āĻŽā§ŒāϞāĻŋāĻ• (Prime) āĻ•āĻŋ āύāĻž āϤāĻž āĻšā§‡āĻ• āĻ•āϰāĻžāϰ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāĨ¤ āϚāϞ⧁āύ āĻāϰ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻ•āĻžāϰāĻŖāϟāĻŋ āĻĻ⧇āϖ⧇ āύāĻŋāχ:

ā§§. āϞ⧁āĻĒāϗ⧁āϞ⧋āϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ

āĻŽā§‹āϟ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻŦ⧇āϰ āĻ•āϰāϤ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ $i$-āĻāϰ āϜāĻ¨ā§āϝ āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒāϟāĻŋ āĻ•āϤāĻŦāĻžāϰ āϚāϞāϛ⧇ āϤāĻžāϰ āϝ⧋āĻ—āĻĢāϞ āĻŦ⧇āϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇:

\[\text{Total Work} = \sqrt{2} + \sqrt{3} + \sqrt{4} + \dots + \sqrt{n}\]

āĻ•ā§āϝāĻžāϞāϕ⧁āϞāĻžāϏ⧇āϰ āχāĻ¨ā§āϟāĻŋāĻ—ā§āϰ⧇āĻļāύ āĻĒāĻĻā§āϧāϤāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāχ āϧāĻžāϰāĻžāϰ āϝ⧋āĻ—āĻĢāϞ āĻŦ⧇āϰ āĻ•āϰāϞ⧇ āĻĻ⧇āĻ–āĻž āϝāĻžā§Ÿ:

\[\int_{2}^{n} \sqrt{x} dx \approx \frac{2}{3} n^{1.5}\]

āϝ⧇āĻšā§‡āϤ⧁ āĻŦāĻŋāĻ—-āĻ“ ($O$) āύ⧋āĻŸā§‡āĻļāύ⧇ āφāĻŽāϰāĻž āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āĻŦāĻž āĻ§ā§āϰ⧁āĻŦāĻ• ($\frac{2}{3}$) āĻŦāĻžāĻĻ āĻĻāĻŋāχ, āϤāĻžāχ āĻšā§‚ā§œāĻžāĻ¨ā§āϤ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻĻāĻžāρ⧜āĻžā§Ÿ: $O(n\sqrt{n})$ āĻŦāĻž $O(n^{1.5})$āĨ¤

ā§Š. āϏāĻšāϜāĻ­āĻžāĻŦ⧇ āĻŦā§‹āĻāĻžāϰ āωāĻĒāĻžā§Ÿ


int count = 0;
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        for (int k = 0; k < n; k++) {
            if (i + j + k < n) count++;
            else break;
        }
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^3)$āĨ¤

āϝāĻĻāĻŋāĻ“ āĻāĻ–āĻžāύ⧇ āĻāĻ•āϟāĻŋ break āĻ¸ā§āĻŸā§‡āϟāĻŽā§‡āĻ¨ā§āϟ āφāϛ⧇, āϝāĻž āĻĻ⧇āϖ⧇ āĻŽāύ⧇ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āĻāϟāĻŋ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻ•āĻŽāĻŋā§Ÿā§‡ āĻĻ⧇āĻŦ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ•āĻ­āĻžāĻŦ⧇ āĻāϟāĻŋ āĻāĻ–āύ⧋ āĻ•āĻŋāωāĻŦāĻŋāĻ• ($n^3$) āĻ•ā§āϝāĻžāϟāĻžāĻ—āϰāĻŋāϤ⧇āχ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύ āĻ•āϰāϛ⧇āĨ¤ āϚāϞ⧁āύ āĻāϰ āĻ•āĻžāϰāĻŖāϗ⧁āϞ⧋ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ āĻ•āϰāĻŋ:

ā§§. āϕ⧇āύ āĻāϟāĻŋ $O(n^3)$?

āϞ⧁āĻĒāϗ⧁āϞ⧋āϰ āĻ—āĻ āύ āϞāĻ•ā§āĻˇā§āϝ āĻ•āϰ⧁āύ:

āĻāĻ–āĻžāύ⧇ break āĻ¸ā§āĻŸā§‡āϟāĻŽā§‡āĻ¨ā§āϟāϟāĻŋ āĻŽā§‚āϞāϤ āĻāĻ•āϟāĻŋ āĻ¤ā§āϰāĻŋāϭ⧁āϜāĻžāĻ•āĻžāϰ āĻŦāĻž āĻĒāĻŋāϰāĻžāĻŽāĻŋāĻĄāĻžāϞ (Pyramidal) āĻ•āĻžāĻœā§‡āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ āϤ⧈āϰāĻŋ āĻ•āϰāϛ⧇āĨ¤ āϝāĻ–āύ $i$ āĻāĻŦāĻ‚ $j$ āϛ⧋āϟ āĻšā§Ÿ, āϤāĻ–āύ $k$ āϞ⧁āĻĒāϟāĻŋ āĻ…āύ⧇āĻ•āĻŦāĻžāϰ āϚāϞ⧇āĨ¤ āϝāĻ–āύ $i$ āĻāĻŦāĻ‚ $j$ āĻŦ⧜ āĻšā§Ÿ, āϤāĻ–āύ $k$ āϞ⧁āĻĒāϟāĻŋ āĻĻā§āϰ⧁āϤ break āĻ•āϰ⧇āĨ¤

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ

āĻāχ āϕ⧋āĻĄāϟāĻŋ āĻŽā§‹āϟ āĻ•āϤāĻŦāĻžāϰ count++ āĻ•āϰāĻŦ⧇, āϤāĻž āĻŦ⧇āϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āφāĻŽāĻžāĻĻ⧇āϰ āύāĻŋāĻšā§‡āϰ āϏāĻŽāĻˇā§āϟāĻŋāϟāĻŋ (Summation) āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇:

\[\sum_{i=0}^{n-1} \sum_{j=0}^{n-i-1} \sum_{k=0}^{n-i-j-1} 1\]

āĻāχ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦāϟāĻŋ āϏāĻŽā§āĻĒāĻ¨ā§āύ āĻ•āϰāϞ⧇ āφāĻŽāϰāĻž āĻāĻ•āϟāĻŋ āĻĢāϞāĻžāĻĢāϞ āĻĒāĻžāχ āϝāĻž āĻŽā§‚āϞāϤ $\frac{n(n+1)(n+2)}{6}$ āĻāϰ āϏāĻŽāĻžāύāĨ¤

āĻāϟāĻŋ āĻŽā§‚āϞāϤ Tetrahedral Number āĻāϰ āϏ⧂āĻ¤ā§āϰāĨ¤ āφāĻŽāϰāĻž āϝāĻĻāĻŋ āĻāχ āϏāĻŽā§€āĻ•āϰāĻŖāϟāĻŋ āĻŦāĻŋāĻ¸ā§āϤ⧃āϤ āĻ•āϰāĻŋ:

\[\frac{n^3 + 3n^2 + 2n}{6}\]

āĻŦāĻŋāĻ—-āĻ“ ($O$) āύ⧋āĻŸā§‡āĻļāύ⧇āϰ āύāĻŋ⧟āĻŽāĻžāύ⧁āϝāĻžā§Ÿā§€, āφāĻŽāϰāĻž āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āϘāĻžāϤāϟāĻŋ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰāĻŋ āĻāĻŦāĻ‚ āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ (āϝ⧇āĻŽāύ $1/6$) āĻŦāĻžāĻĻ āĻĻāĻŋāχāĨ¤ āĻĢāϞ⧇ āĻšā§‚ā§œāĻžāĻ¨ā§āϤ āĻĢāϞāĻžāĻĢāϞ āĻĻāĻžāρ⧜āĻžā§Ÿ $O(n^3)$āĨ¤

ā§Š. āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ

āϝāĻĻāĻŋ $n = 100$ āĻšā§Ÿ:

āϝāĻĻāĻŋāĻ“ break āĻāϰ āĻ•āĻžāϰāϪ⧇ āĻ…āĻĒāĻžāϰ⧇āĻļāύ āϏāĻ‚āĻ–ā§āϝāĻž āĻĒā§āϰāĻžā§Ÿ ā§Ŧ āϗ⧁āĻŖ āĻ•āĻŽā§‡ āϗ⧇āϛ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽāĻŋāĻ• āĻ—ā§āϰ⧋āĻĨ āϰ⧇āϟ āĻŦāĻž āχāύāĻĒ⧁āϟ āĻŦāĻžā§œāĻžāϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āϏāĻŽā§Ÿ āĻŦāĻžā§œāĻžāϰ āĻšāĻžāϰ āĻāĻ–āύ⧋ $n^3$ āĻ…āύ⧁āϝāĻžā§Ÿā§€āχ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāĻŋāϤ āĻšāĻšā§āϛ⧇āĨ¤


void f(int n, int depth) {
    if (depth == 0) return;
    for (int i = 0; i < n; i++) {
        print(i);
    }
    f(n, depth - 1);
    f(n, depth - 1);
}
// Called as: f(n, log2(n))

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^2)$āĨ¤


for (int i = 1; i <= n; i++) {
    for (int j = i; j <= n; j += i) {
        for (int k = j; k <= n; k += j) {
            ans++;
        }
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n \log^2 n)$āĨ¤

ā§§. āϞ⧁āĻĒāϗ⧁āϞ⧋āϰ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āĻāχ āϕ⧋āĻĄāϟāĻŋāϤ⧇ āϤāĻŋāύāϟāĻŋ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āϞ⧁āĻĒ āĻ°ā§Ÿā§‡āϛ⧇ āϝāĻžāĻĻ⧇āϰ āĻ•āĻžāĻœā§‡āϰ āϧāϰāĻŖ āύāĻŋāĻšā§‡ āĻĻ⧇āĻ“ā§ŸāĻž āĻšāϞ⧋:

⧍. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ (Harmonic Series)

āĻĒ⧁āϰ⧋ āĻ•āĻžāĻœā§‡āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻŦ⧇āϰ āĻ•āϰāϤ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āύāĻŋāĻšā§‡āϰ āϏāĻžāĻŽā§‡āĻļāύāϟāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇: \(\sum_{i=1}^{n} \sum_{j=i, 2i, \dots}^{n} \frac{n}{j}\)

āφāĻŽāϰāĻž āϜāĻžāύāĻŋ āϝ⧇, āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ $i$-āĻāϰ āϜāĻ¨ā§āϝ $j$-āĻāϰ āĻŽāĻžāύāϗ⧁āϞ⧋ āĻšāϞ⧋ $i \times m$ (āϝ⧇āĻ–āĻžāύ⧇ $m = 1, 2, \dots, n/i$). āϤāĻžāĻšāϞ⧇ āϭ⧇āϤāϰ⧇āϰ āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āϏāĻŽā§āĻŽāĻŋāϞāĻŋāϤ āĻ•āĻžāϜ:

\(\sum_{j \in \{i, 2i, \dots\}} \frac{n}{j} = \frac{n}{i} + \frac{n}{2i} + \frac{n}{3i} + \dots = \frac{n}{i} (1 + \frac{1}{2} + \frac{1}{3} + \dots + \frac{1}{n/i})\)āĻšāĻžāϰāĻŽā§‹āύāĻŋāĻ• āϏāĻŋāϰāĻŋāĻœā§‡āϰ āϧāĻ°ā§āĻŽ āĻ…āύ⧁āϝāĻžā§Ÿā§€, $(1 + \frac{1}{2} + \dots + \frac{1}{x}) \approx \ln(x)$āĨ¤āϏ⧁āϤāϰāĻžāĻ‚, āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ $i$-āĻāϰ āϜāĻ¨ā§āϝ āĻ•āĻžāϜ āĻšāĻšā§āϛ⧇: $\frac{n}{i} \log(\frac{n}{i})$āĨ¤āĻāĻ–āύ āϏāĻŦ $i$-āĻāϰ āϜāĻ¨ā§āϝ āĻŽā§‹āϟ āĻ•āĻžāϜ:\(\sum_{i=1}^{n} \frac{n}{i} \log(\frac{n}{i}) \leq \sum_{i=1}^{n} \frac{n}{i} \log(n) = n \log(n) \sum_{i=1}^{n} \frac{1}{i}\)āϝ⧇āĻšā§‡āϤ⧁ $\sum \frac{1}{i}$ āφāĻŦāĻžāϰāĻ“ āĻāĻ•āϟāĻŋ āĻšāĻžāϰāĻŽā§‹āύāĻŋāĻ• āϏāĻŋāϰāĻŋāϜ āϝāĻž $\log n$ āĻāϰ āϏāĻŽāĻžāύ, āϤāĻžāχ āĻšā§‚ā§œāĻžāĻ¨ā§āϤ āĻĢāϞāĻžāĻĢāϞ āĻĻāĻžāρ⧜āĻžā§Ÿ:\(n \log n \times \log n = O(n \log^2 n)\)

āϏāĻšāϜāĻ­āĻžāĻŦ⧇ āĻŽāύ⧇ āϰāĻžāĻ–āĻžāϰ āĻ•ā§ŒāĻļāϞ:

āϝāĻ–āύāχ āφāĻĒāύāĻŋ āĻĻ⧇āĻ–āĻŦ⧇āύ āϕ⧋āύ⧋ āϞ⧁āĻĒ j += i āĻŦāĻž k += j āĻ¸ā§āϟāĻžāχāϞ⧇ āϚāϞāϛ⧇ (āĻ…āĻ°ā§āĻĨāĻžā§Ž āφāϗ⧇āϰ āϞ⧁āĻĒ⧇āϰ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻĻāĻŋā§Ÿā§‡ āϞāĻžāĻĢ āĻĻāĻŋāĻšā§āϛ⧇), āϏ⧇āĻ–āĻžāύ⧇ Harmonic Series āĻŦāĻž $\log n$ āĻāϰ āĻĒā§āϰāĻ­āĻžāĻŦ āϤ⧈āϰāĻŋ āĻšā§ŸāĨ¤ āĻāĻ–āĻžāύ⧇ āĻĻ⧁āϟāĻŋ āĻāĻŽāύ āϞ⧁āĻĒ āĻĨāĻžāĻ•āĻžā§Ÿ āφāĻŽāϰāĻž $n \times \log n \times \log n$ āĻĒāĻžāĻšā§āĻ›āĻŋāĨ¤


for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
        int temp = j;
        while (temp > 0) {
            temp = temp & (temp - 1);
            count++;
        }
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^2 \log n)$āĨ¤

ā§§. āϞ⧁āĻĒāϗ⧁āϞ⧋āϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

⧍. āĻŦāĻŋāϟ āĻŽā§āϝāĻžāύāĻŋāĻĒ⧁āϞ⧇āĻļāύ āĻŸā§āϰāĻŋāĻ•: Brian Kernighan’s Algorithm

temp & (temp - 1) āĻ…āĻĒāĻžāϰ⧇āĻļāύāϟāĻŋ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻžāϰ āĻŦāĻžāχāύāĻžāϰāĻŋ āϰāĻŋāĻĒā§āϰ⧇āĻœā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻĨ⧇āϕ⧇ āϏāĻŦāĻĨ⧇āϕ⧇ āĻĄāĻžāύāĻĻāĻŋāϕ⧇āϰ āϏ⧇āϟ āĻŦāĻŋāϟ (set bit āĻŦāĻž $1$) āϟāĻŋāϕ⧇ āϏāϰāĻŋā§Ÿā§‡ āĻĻā§‡ā§ŸāĨ¤

āϏāĻšāϜ āĻ•āĻĨāĻžā§Ÿ, āĻāχ āϞ⧁āĻĒāϟāĻŋ āϤāϤāĻŦāĻžāϰ āϚāϞāĻŦ⧇ āϝāϤāϗ⧁āϞ⧋ $1$ āĻŦāĻž Set Bits āϏāĻ‚āĻ–ā§āϝāĻžāϟāĻŋāϰ āĻŦāĻžāχāύāĻžāϰāĻŋ āϰ⧂āĻĒ⧇ āφāϛ⧇āĨ¤

ā§Š. āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻšāĻŋāϏāĻžāĻŦ

āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž $n$ āĻāϰ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻ•āϤāϗ⧁āϞ⧋ āϏ⧇āϟ āĻŦāĻŋāϟ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇? āωāĻ¤ā§āϤāϰ āĻšāϞ⧋ $\mathbf{\log_2 n}$āĨ¤āĻ…āĻ°ā§āĻĨāĻžā§Ž, āĻĒā§āϰāϤāĻŋāϟāĻŋ $j$-āĻāϰ āϜāĻ¨ā§āϝ āĻāχ while āϞ⧁āĻĒāϟāĻŋ āĻ—ā§œā§‡ $\log n$ āĻāϰ āĻŦ⧇āĻļāĻŋ āϚāϞāϤ⧇ āĻĒāĻžāϰ⧇ āύāĻžāĨ¤

āϤāĻžāĻšāϞ⧇ āĻŽā§‹āϟ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻĻāĻžāρ⧜āĻžā§Ÿ:

\[\text{Outer Loops} \times \text{Bitwise Loop} = n \times n \times \log n = \mathbf{O(n^2 \log n)}\]
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        int x = n;
        while (x > 1) {
            x = x / 3;
        }
        sum++;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^2 \log_3 n)$āĨ¤

ā§§. āϞ⧁āĻĒāϗ⧁āϞ⧋āϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

āφāĻŽāϰāĻž āϜāĻžāύāĻŋ, āϕ⧋āύ⧋ āϏāĻ‚āĻ–ā§āϝāĻžāϕ⧇ āϝāĻĻāĻŋ āĻĒā§āϰāϤāĻŋ āϧāĻžāĻĒ⧇ āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻ§ā§āϰ⧁āĻŦāĻ• (āĻāĻ–āĻžāύ⧇ $3$) āĻĻāĻŋāϝāĻŧ⧇ āĻ­āĻžāĻ— āĻ•āϰāĻž āĻšāϝāĻŧ āϝāϤāĻ•ā§āώāĻŖ āύāĻž āϏ⧇āϟāĻŋ $1$-āĻ āĻĒ⧌āρāĻ›āĻžāϝāĻŧ, āϤāĻŦ⧇ āϏ⧇āχ āϞ⧁āĻĒāϟāĻŋ āĻŽā§‹āϟ $\log_{\text{base}} (\text{value})$ āĻŦāĻžāϰ āϚāϞ⧇āĨ¤ āĻāĻ–āĻžāύ⧇ āĻŦ⧇āϏ āĻšāϞ⧋ $3$ āĻāĻŦāĻ‚ āĻ­ā§āϝāĻžāϞ⧁ āĻšāϞ⧋ $n$, āϤāĻžāχ āĻāχ āϞ⧁āĻĒāϟāĻŋ āϚāϞ⧇ $\log_3 n$ āĻŦāĻžāϰāĨ¤


for (int i = 0; i < n; i++) {
    for(int j=1; j<i*i*i; j++){
        sum++;
    }
}

āĻāχ āϕ⧋āĻĄāϟāĻŋāϰ āϟāĻžāχāĻŽ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏāĻŋāϟāĻŋ āĻšāϞ⧋ $O(n^4)$āĨ¤

ā§§. āϞ⧁āĻĒ āĻĻ⧁āϟāĻŋāϰ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ

$O(2^n)$ āĻŦāĻž Exponential Time

int fibonacci(int n) {
    if (n <= 1) return n;
    // āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ āφāϰāĻ“ ⧍āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύāϕ⧇ āĻ•āϞ āĻ•āϰāϛ⧇
    return fibonacci(n - 1) + fibonacci(n - 2);
}

āĻāĻ–āĻžāύ⧇ āϕ⧇āύ āĻ•āĻžāϜ (Operations) āĻĻā§āĻŦāĻŋāϗ⧁āĻŖ āĻšāĻšā§āϛ⧇? āϝāĻ–āύ āφāĻĒāύāĻŋ fibonacci(5) āĻ•āϞ āĻ•āϰ⧇āύ:

āϏāĻšāϜ āĻ•āĻĨāĻž: āϝ⧇āĻ–āĻžāύ⧇ āĻāĻ•āϟāĻŋ āϏāĻŽāĻ¸ā§āϝāĻžāϰ āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāϤ⧇ āĻ—āĻŋā§Ÿā§‡ āφāĻĒāύāĻžāϕ⧇ āĻŦāĻžāϰāĻŦāĻžāϰ āĻāĻ•āχ āĻ•āĻžāϜ “āĻļāĻžāĻ–āĻž-āĻĒā§āϰāĻļāĻžāĻ–āĻžâ€ āφāĻ•āĻžāϰ⧇ āĻ•āϰāϤ⧇ āĻšā§Ÿ, āϏ⧇āĻ–āĻžāύ⧇āχ $O(2^n)$ āϤ⧈āϰāĻŋ āĻšā§ŸāĨ¤ ___

Space Complexity

āωāĻĻāĻžāĻšāϰāĻŖ ā§§: $O(1)$ Auxiliary Space (āĻĻāĻ•ā§āώ āĻĒāĻĻā§āϧāϤāĻŋ)

āĻāĻ–āĻžāύ⧇ āφāĻŽāϰāĻž āχāύāĻĒ⧁āϟ āĻ…ā§āϝāĻžāϰ⧇āϰ āĻŦāĻžāχāϰ⧇ āĻļ⧁āϧ⧁ āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ sum āύāĻŋāĻšā§āĻ›āĻŋāĨ¤

int solve(int arr[], int n) {
    int sum = 0; // āĻāϟāĻž Auxiliary Space
    for (int i = 0; i < n; i++) {
        sum += arr[i];
    }
    return sum;
}

āωāĻĻāĻžāĻšāϰāĻŖ ⧍: $O(n)$ Auxiliary Space (āĻ•āĻŽ āĻĻāĻ•ā§āώ āĻĒāĻĻā§āϧāϤāĻŋ)

āϧāϰ⧋, āϝ⧋āĻ— āĻ•āϰāĻžāϰ āφāϗ⧇ āφāĻŽāϰāĻž āϏāĻŦ āϏāĻ‚āĻ–ā§āϝāĻž āĻ•āĻĒāĻŋ āĻ•āϰ⧇ āĻ…āĻ¨ā§āϝ āĻāĻ•āϟāĻž āĻ…ā§āϝāĻžāϰ⧇āϤ⧇ āϰāĻžāĻ–āĻ›āĻŋāĨ¤

int solve(int arr[], int n) {
    int tempArr[n]; // āĻāϟāĻž Auxiliary Space
    for (int i = 0; i < n; i++) {
        tempArr[i] = arr[i]; // āĻ•āĻĒāĻŋ āĻ•āϰāĻ›āĻŋ
    }
    // āĻāϰāĻĒāϰ āϝ⧋āĻ— āĻ•āϰāĻ›āĻŋ...
}

ā§§. $O(1)$ Space (āĻ•āύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āĻ¸ā§āĻĒ⧇āϏ)

āĻāĻ–āĻžāύ⧇ āχāύāĻĒ⧁āĻŸā§‡āϰ āϏāĻžāχāϜ āϝāĻžāχ āĻšā§‹āĻ•, āφāĻŽāϰāĻž āĻŽāĻžāĻ¤ā§āϰ ā§§-⧍āϟāĻž āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻ›āĻŋāĨ¤ āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻāĻ•āĻĻāĻŽ āĻĢāĻŋāĻ•ā§āϏāĻĄāĨ¤

// findMax: āĻāĻ–āĻžāύ⧇ āĻļ⧁āϧ⧁ 'maxVal' āφāϰ 'i' āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āφāϛ⧇
int findMax(int arr[], int n) {
    int maxVal = arr[0]; // ā§§āϟāĻŋ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ
    for (int i = 1; i < n; i++) { // āϞ⧁āĻĒ⧇āϰ āϜāĻ¨ā§āϝ ā§§āϟāĻŋ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ
        if (arr[i] > maxVal) maxVal = arr[i];
    }
    return maxVal;
}