WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Software Engineering · Basic · question 8 of 100

Explain the concept of Big O notation and provide examples of different time complexities.?

📕 Buy this interview preparation book: 100 Software Engineering questions & answers — PDF + EPUB for $5

Big O notation is a mathematical notation that describes the upper bound on the time or space complexity of an algorithm. In simpler words, it expresses the rate at which an algorithm’s runtime grows as the input size increases.

An algorithm’s time complexity is typically expressed in terms of its worst-case performance, which is usually the case when analyzing algorithms. Big O notation allows us to compare the scalability of different algorithms and determine which algorithm is more efficient for a given problem.

Here are some commonly used time complexities and their examples:

1. O(1) - Constant Time Complexity: An algorithm with constant complexity takes a constant amount of time to perform an operation, regardless of the input size. For example, accessing a specific element in an array or a hash table.

def constant_example(a):
  return a[0]

2. O(logn) - Logarithmic Time Complexity: An algorithm with logarithmic complexity divides the input size by a constant factor at every iteration. This is typically seen in algorithms that involve binary search or divide and conquer techniques.

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

3. O(n) - Linear Time Complexity: An algorithm with a linear complexity takes an amount of time proportional to the size of the input. For example, iterating through an array or a linked list.

def linear_example(a):
  for i in range(len(a)):
    print(a[i])

4. O(nlogn) - Linearithmic Time Complexity: An algorithm with a linearithmic complexity involves an algorithm that applies logarithmic complexity inside a loop that runs through the input size once. This time complexity is commonly seen in sorting algorithms that employ a divide and conquer strategy.

def merge_sort(a):
  if len(a) <= 1:
    return a
  
  mid = len(a) // 2
  left = merge_sort(a[:mid])
  right = merge_sort(a[mid:])

  return merge(left, right)

def merge(left, right):
  result = []
  i, j = 0, 0
  while i < len(left) and j < len(right):
    if left[i] < right[j]:
      result.append(left[i])
      i += 1
    else:
      result.append(right[j])
      j += 1

  result += left[i:]
  result += right[j:]
  return result

5. O(n2)- Quadratic Time Complexity: An algorithm with quadratic complexity takes an amount of time proportional to the square of the input size. This complexity is commonly seen in algorithms that involve nested loops or operations on matrices.

def quadratic_example(a):
  n = len(a)
  for i in range(n):
    for j in range(n):
      print(a[i][j])

6. O(2n) - Exponential Time Complexity: An algorithm with exponential complexity takes an amount of time that grows exponentially with the input size. This is commonly seen in brute force algorithms that generate all possible combinations of the input.

def fibonacci(n):
  if n <= 1:
    return n
  return fibonacci(n-1) + fibonacci(n-2)

In conclusion, it is essential to consider the time complexity of an algorithm before selecting it for a given problem. Big O notation provides a convenient way to analyze the scalability of an algorithm and compare it with other algorithms.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Software Engineering interview — then scores it.
📞 Practice Software Engineering — free 15 min
📕 Buy this interview preparation book: 100 Software Engineering questions & answers — PDF + EPUB for $5

All 100 Software Engineering questions · All topics