DEV Community

Lakh Bawa
Lakh Bawa

Posted on

Easy way to find the Time Complexity of an Algorithm

Time complexity is considered one of the toughest topics for beginners who are just starting with Problem-Solving. Here, I am providing the time complexity analysis cheat sheet. I hope this helps. Please let me know if you have any questions.

Time Complexity Analysis Cheatsheet

Quick Reference Table

O(1)       - Constant time
O(log n)   - Logarithmic (halving/doubling)
O(n)       - Linear (single loop)
O(n log n) - Linearithmic (efficient sorting)
O(n²)      - Quadratic (nested loops)
O(2ⁿ)      - Exponential (recursive doubling)
O(n!)      - Factorial (permutations)
Enter fullscreen mode Exit fullscreen mode

Identifying Patterns

1. O(1) - Constant

# Look for:
- Direct array access
- Basic math operations
- Fixed loops
- Hash table lookups

# Examples:
arr[0]
x + y
for i in range(5)
hashmap[key]
Enter fullscreen mode Exit fullscreen mode

2. O(log n) - Logarithmic

# Look for:
- Halving/Doubling
- Binary search patterns
- Tree traversal by level

# Examples:
while n > 0:
    n = n // 2

left, right = 0, len(arr)-1
while left <= right:
    mid = (left + right) // 2
Enter fullscreen mode Exit fullscreen mode

3. O(n) - Linear

# Look for:
- Single loops
- Array traversal
- Linear search
- Hash table building

# Examples:
for num in nums:
    # O(1) operation
    total += num

for i in range(n):
    # O(1) operation
    arr[i] = i
Enter fullscreen mode Exit fullscreen mode

4. O(n log n) - Linearithmic

# Look for:
- Efficient sorting
- Divide and conquer
- Tree operations with traversal

# Examples:
nums.sort()
sorted(nums)
merge_sort(nums)
Enter fullscreen mode Exit fullscreen mode

5. O(n²) - Quadratic

# Look for:
- Nested loops
- Simple sorting
- Matrix traversal
- Comparing all pairs

# Examples:
for i in range(n):
    for j in range(n):
        # O(1) operation

# Pattern finding
for i in range(n):
    for j in range(i+1, n):
        # Compare pairs
Enter fullscreen mode Exit fullscreen mode

6. O(2ⁿ) - Exponential

# Look for:
- Double recursion
- Power set
- Fibonacci recursive
- All subsets

# Examples:
def fib(n):
    if n <= 1: return n
    return fib(n-1) + fib(n-2)

def subsets(nums):
    if not nums: return [[]]
    result = subsets(nums[1:])
    return result + [nums[0:1] + r for r in result]
Enter fullscreen mode Exit fullscreen mode

Common Operations Time Complexity

Array/List Operations

# O(1)
arr[i]              # Access
arr.append(x)       # Add end
arr.pop()           # Remove end

# O(n)
arr.insert(i, x)    # Insert middle
arr.remove(x)       # Remove by value
arr.index(x)        # Find index
min(arr), max(arr)  # Find min/max
Enter fullscreen mode Exit fullscreen mode

Dictionary/Set Operations

# O(1) average
d[key]              # Access
d[key] = value      # Insert
key in d            # Check existence
d.get(key)          # Get value

# O(n)
len(d)              # Size
d.keys()            # Get keys
d.values()          # Get values
Enter fullscreen mode Exit fullscreen mode

String Operations

# O(n)
s + t               # Concatenation
s.find(t)           # Substring search
s.replace(old, new) # Replace
''.join(list)       # Join

# O(n²) potential
s += char           # Repeated concatenation
Enter fullscreen mode Exit fullscreen mode

Loop Analysis

Single Loop

# O(n)
for i in range(n):
    # O(1) operations

# O(n/2) = O(n)
for i in range(0, n, 2):
    # Skip elements still O(n)
Enter fullscreen mode Exit fullscreen mode

Nested Loops

# O(n²)
for i in range(n):
    for j in range(n):
        # O(1) operations

# O(n * m)
for i in range(n):
    for j in range(m):
        # Different sizes

# O(n²/2) = O(n²)
for i in range(n):
    for j in range(i, n):
        # Triangular still O(n²)
Enter fullscreen mode Exit fullscreen mode

Multiple Loops

# O(n + m)
for i in range(n):
    # O(1)
for j in range(m):
    # O(1)

# O(n + n²) = O(n²)
for i in range(n):
    # O(1)
for i in range(n):
    for j in range(n):
        # O(1)
Enter fullscreen mode Exit fullscreen mode

Recursive Analysis

Linear Recursion

# O(n)
def factorial(n):
    if n <= 1: return 1
    return n * factorial(n-1)
Enter fullscreen mode Exit fullscreen mode

Binary Recursion

# O(2ⁿ)
def fibonacci(n):
    if n <= 1: return n
    return fibonacci(n-1) + fibonacci(n-2)
Enter fullscreen mode Exit fullscreen mode

Divide & Conquer

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

Optimization Red Flags

Hidden Loops

# String operations
for c in string:
    newStr += c  # O(n²)

# List comprehension
[x for x in range(n) for y in range(n)]  # O(n²)
Enter fullscreen mode Exit fullscreen mode

Built-in Functions

len()           # O(1)
min(), max()    # O(n)
sorted()        # O(n log n)
list.index()    # O(n)
Enter fullscreen mode Exit fullscreen mode

Tips for Analysis

  1. Count nested loops
  2. Check recursive branching
  3. Consider hidden operations
  4. Look for divide & conquer
  5. Check built-in function complexity
  6. Consider average vs worst case
  7. Watch for loop variables
  8. Consider input constraints

Thank you for reading, please give the thumbs up on the post if you found this helpful. Cheers!

Top comments (0)