#1 India's Top IT Training Institute

×

About Uncodemy

Know more about who we are and what we stand for.

About Us

About Us

Discover our mission to equip individuals with essential IT skills and industry expertise.

Read More →
UnCodeMy Gallery

UnCodeMy Gallery

Explore highlights from our IT training sessions and success stories.

Read More →
×

Free Resources

Learn, practice and plan your career — bilkul free.

Tutorials

Tutorials

Step-by-step written tutorials to learn any technology at your own pace.

Read More →
Free Counselling

Free Counselling

Book a free video counselling session and pick the right course for you.

Read More →
Online Compiler

Online Compiler

Write, run and test your code online — no setup required.

Read More →
Fundamentals

Big O Notation in Data Structures: Time and Space Complexity

Big O Notation is the mathematical notation used to describe the limiting behavior of a function when the argument tends toward infinity. In computer science, it is the standard tool for analyzing the time complexity and space complexity of algorithms. Big O describes the worst-case scenario, providing an upper bound on the growth rate of an algorithm.

What is Big O Notation?

Big O Notation expresses how the runtime or memory usage of an algorithm scales with the size of the input. It focuses on the dominant term and ignores constants and lower-order terms.

If f(n) = 3n² + 2n + 1, then f(n) = O(n²)

Because as n grows, the n² term dominates.

Why Big O Matters

  • Predicts Scalability: Tells us how an algorithm performs as input size increases.
  • Enables Comparison: Allows objective comparison between different algorithms.
  • Identifies Bottlenecks: Helps locate performance issues in code.
  • Industry Standard: Used in interviews, system design, and performance analysis.

Common Big O Complexity Classes

NotationNameExampleGrowth (n=10)Growth (n=100)
O(1)ConstantArray access11
O(log n)LogarithmicBinary search~3~7
O(n)LinearLinear search10100
O(n log n)LinearithmicMerge sort~33~664
O(n²)QuadraticBubble sort10010,000
O(n³)CubicMatrix multiplication1,0001,000,000
O(2ⁿ)ExponentialSubset sum (naive)1,0241.27e+30
O(n!)FactorialTSP (naive)3,628,8009.33e+157

Visualizing Growth

When n = 100:

  • O(1): 1 operation (blazing fast)
  • O(log n): ~7 operations
  • O(n): 100 operations
  • O(n log n): ~664 operations
  • O(n²): 10,000 operations
  • O(2ⁿ): ~1.27 × 10³⁰ operations (practically impossible)

Time Complexity Examples

O(1) — Constant Time

Independent of input size.

def constant_time(arr):
    return arr[0]  # Always one operation

O(log n) — Logarithmic Time

Each step reduces the input size by a factor.

def binary_search(arr, target):
    low, high = 0, len(arr) - 1
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            low = mid + 1
        else:
            high = mid - 1
    return -1

O(n) — Linear Time

Single loop over the input.

def linear_time(arr):
    total = 0
    for x in arr:
        total += x
    return total

O(n log n) — Linearithmic Time

Common in efficient sorting algorithms.

def merge_sort(arr):  # O(n log n)
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

O(n²) — Quadratic Time

Nested loops over the input.

def quadratic_time(arr):
    for i in range(len(arr)):
        for j in range(len(arr)):
            print(arr[i], arr[j])

O(2ⁿ) — Exponential Time

Recursive solutions that branch exponentially.

def fibonacci(n):  # Naive recursive
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)
# Each call branches into two more calls

Space Complexity

Space complexity measures the amount of memory an algorithm uses relative to the input size. It includes:

  • Fixed part: Memory for constants, program code, and simple variables.
  • Variable part: Memory for data structures, recursion stack, and dynamically allocated memory.

Space Complexity Examples

def sum_array(arr):  # O(1) space
    total = 0
    for x in arr:
        total += x
    return total

def copy_array(arr):  # O(n) space
    return arr[:]  # Creates a new array of size n

def recursive_sum(arr):  # O(n) space (call stack)
    if not arr:
        return 0
    return arr[0] + recursive_sum(arr[1:])

Comparing Complexities

nO(1)O(log n)O(n)O(n log n)O(n²)O(2ⁿ)
1101012
101310331001,024
1001710066410,0001.27e+30
1,0001101,0009,9661,000,000~10³⁰¹
10,00011310,000132,877100,000,000~10³⁰¹⁰

How to Analyze Complexity

Step-by-Step Guide

  1. Identify the input size (n): Usually the number of elements.
  2. Count the operations: Loops, recursive calls, etc.
  3. Focus on the dominant term: Ignore constants and lower-order terms.
  4. Consider worst-case: Big O describes the upper bound.

Common Patterns

  • Single loop: O(n)
  • Nested loops: O(n²), O(n³), etc.
  • Divide and conquer: Often O(n log n) or O(log n)
  • Recursive branching: Often O(2ⁿ) or O(n!)
  • Hash operations: Usually O(1) average

Key Takeaways

  • Big O Notation is the standard for analyzing algorithm efficiency.
  • It describes the worst-case scenario and ignores constants and lower-order terms.
  • Time complexity measures runtime; space complexity measures memory usage.
  • Common classes: O(1), O(log n), O(n), O(n log n), O(n²), O(2ⁿ), O(n!).
  • Understanding Big O is essential for writing efficient, scalable code.

Ready to master Data Structures & Algorithms?

Learn DSA hands-on with mentor-led sessions, real interview practice, and placement support.

Explore Course