ScholarQuill logoScholarQuillUniversity Notes
  • Notes
  • Past Papers
  • Blogs
  • Todo
Login
ScholarQuill logoScholarQuillUniversity Notes
Login
NotesPast PapersBlogsTodo
More
SubjectsDiscussionCGPA CalculatorGPA CalculatorStudent PortalCourse Outline
About
About usPrivacy PolicyReportContact
Notes
Past Papers
Blogs
Todo
Analytics
    Current Subject
    🧩
    Design & Analysis of Algorithms
    DC-321
    Progress0 / 28 topics
    Topics
    1. Introduction2. Role of Algorithms in Computing3. Analysis on Nature of Input and Size of Input4. Asymptotic Notations5. Big-O Notation6. Big-Ω Notation7. Big-Θ Notation8. Little-o Notation9. Little-ω Notation10. Sorting Algorithm Analysis11. Loop Invariants12. Recursion and Recurrence Relations13. Algorithm Design Techniques14. Brute Force Approach15. Divide-and-Conquer Approach16. Merge Sort17. Quick Sort18. Greedy Approach19. Dynamic Programming20. Elements of Dynamic Programming21. Search Trees22. Heaps23. Hashing24. Graph Algorithms25. Shortest Paths26. Sparse Graphs27. String Matching28. Introduction to Complexity Classes
    DC-321›Little-o Notation
    Design & Analysis of AlgorithmsTopic 8 of 28

    Little-o Notation

    8 minread
    1,300words
    Intermediatelevel

    Little-o Notation

    Little-o notation is used in algorithm analysis to describe an upper bound that is not tight, meaning the algorithm’s running time or space complexity grows strictly slower than a given function. In other words, little-o represents the behavior of a function that grows faster than another function, but not asymptotically equal to it.

    In simple terms, little-o notation is used to express that a function grows strictly slower than another function as the input size increases, but not at the same rate. It provides a way to describe a situation where an algorithm's performance is upper bounded, but the bound is not tight — the function grows strictly smaller than the given upper bound.


    1. Definition of Little-o

    Mathematically, we say that f(n) is o(g(n)) if, for any constant c > 0, there exists a constant n₀ such that:

    lim⁡n→∞f(n)g(n)=0\lim_{n \to \infty} \frac{f(n)}{g(n)} = 0n→∞lim​g(n)f(n)​=0

    This means that as n grows large, the function f(n) becomes insignificant compared to g(n). More formally, f(n) grows strictly slower than g(n), and f(n) is asymptotically smaller than g(n) as n increases.

    • Upper Bound: Little-o notation is used to define an upper bound that is not tight, meaning the function grows strictly slower than the given bound.
    • Asymptotically Smaller: It indicates that, for large n, f(n) is much smaller than g(n), and the ratio f(n)/g(n) approaches zero.

    2. Why Little-o is Important

    • Upper Bound Without Tightness: Little-o provides an upper bound on an algorithm's performance, but it ensures that the algorithm’s performance is strictly smaller than the given bound.
    • Clarifying Growth Rates: Little-o notation is helpful when we want to show that one algorithm’s growth rate is significantly slower than another, but not asymptotically equivalent.
    • Refining Analysis: It helps us distinguish between cases where one algorithm has a smaller growth rate than another, but still grows faster than a particular function.

    3. Little-o vs Big-O Notation

    The key difference between Little-o and Big-O is the tightness of the bound:

    • Big-O (O) provides an upper bound on the growth rate, but it allows for the possibility that the two functions grow at the same rate asymptotically (up to constant factors).
    • Little-o (o) provides an upper bound where the function grows strictly slower than the bound. It tells us that the function is asymptotically smaller than the given function.

    In terms of relationships:

    f(n)=O(g(n))does not necessarily implyf(n)=o(g(n))f(n) = O(g(n)) \quad \text{does not necessarily imply} \quad f(n) = o(g(n))f(n)=O(g(n))does not necessarily implyf(n)=o(g(n))
    • Big-O allows the possibility that f(n) could grow at the same rate as g(n) (up to constant factors).
    • Little-o strictly implies that f(n) grows strictly slower than g(n).

    4. Common Examples of Little-o Notation

    a. o(1) – Strictly Constant Time Complexity

    • A function that grows slower than a constant value is described as o(1).
    • Example: A function that has f(n) = n / (n + 1) is o(1).
      • Explanation: As n increases, f(n) approaches 1 but is always smaller than 1 for all n.

    b. o(n) – Strictly Linear Time Complexity

    • A function that grows strictly slower than n can be expressed as o(n).
    • Example: f(n) = log n is o(n).
      • Explanation: As n grows larger, log n grows much slower than n.

    c. o(n²) – Strictly Quadratic Time Complexity

    • A function that grows strictly slower than n² can be expressed as o(n²).
    • Example: f(n) = n log n is o(n²).
      • Explanation: While n log n grows faster than n, it grows strictly slower than n².

    d. o(n log n) – Strictly Log-Linear Time Complexity

    • f(n) = n is o(n log n).
      • Explanation: n grows slower than n log n, meaning n is asymptotically smaller.

    5. Visualizing Little-o Notation

    Graphically, little-o notation expresses that the growth of f(n) is smaller than g(n) as n increases.

    If you plot f(n) and g(n) on a graph, you will see that for large values of n, the function f(n) will always stay below g(n) and will get closer to zero as n increases, but g(n) will continue to grow without bound.

    For example:

    • f(n) = n log n and g(n) = n²: As n becomes large, n log n grows slower than n² and eventually becomes negligible compared to n². Hence, f(n) = o(n²).

    6. When to Use Little-o Notation

    • To express a function that grows slower than a given bound: Little-o is ideal when we want to express that an algorithm's time or space complexity is asymptotically smaller than a function, without being exactly equal to it.

    • Refining bounds: Little-o notation helps refine upper bounds. If we have an algorithm with time complexity O(n²), but we know it grows strictly slower than n², we can use o(n²) to express this more accurately.

    • Asymptotic Comparison: Little-o is helpful in comparing different algorithms with different growth rates. For example, if an algorithm has O(n log n) complexity and another has O(n²), we can show that the first is o(n²), indicating that its growth rate is strictly smaller.


    7. Examples of Little-o in Algorithm Analysis

    Example 1: Algorithm A with O(n²) and Algorithm B with O(n log n)

    • Algorithm A has a time complexity of O(n²), and Algorithm B has a time complexity of O(n log n).
    • Using Little-o, we can express that Algorithm B grows strictly slower than Algorithm A, which would be written as: nlog⁡n=o(n2)n \log n = o(n²)nlogn=o(n2) This means that Algorithm B will always have better (slower-growing) performance compared to Algorithm A for sufficiently large n.

    Example 2: Algorithm with O(n) vs. Algorithm with O(n log n)

    • Consider an algorithm with O(n) complexity and another with O(n log n).
    • We can say that the first algorithm grows strictly slower than the second, and express it as: n=o(nlog⁡n)n = o(n \log n)n=o(nlogn) This tells us that n grows strictly slower than n log n, so the first algorithm will generally outperform the second for large input sizes.

    Summary

    Little-o notation provides a way to describe an upper bound that is not tight—it indicates that one function grows strictly slower than another function as the input size increases. Some key points include:

    • Little-o describes an upper bound where the function grows strictly smaller than the given function as n increases.
    • It is used when you want to express that an algorithm’s time or space complexity is asymptotically smaller than a particular function, but not equal to it.
    • Little-o is essential for differentiating between algorithms that may have similar time complexities but differ in growth rates.
    • It is used when we want to show that the growth rate of a function is strictly slower than another function, and that function’s performance will eventually be negligible for large inputs.

    In essence, little-o notation is useful for expressing the slower growth of an algorithm compared to another, highlighting its upper bound without it being asymptotically equivalent to the comparison function.

    Previous topic 7
    Big-Θ Notation
    Next topic 9
    Little-ω Notation

    Past Papers

    Open this section to load past papers

    Click on Show Past Papers to see past papers.
    On This Page
      Reading Stats
      Est. reading time8 min
      Word count1,300
      Code examples0
      DifficultyIntermediate