Hello! Welcome back to our course on Data Structures and Algorithms.
In the last lesson, we established why complexity analysis is crucial for coding interviews. We learned that Big-O notation is the language we use to describe how an algorithm's performance scales, and we covered the basic rules: analyze the worst case, and ignore constants and less-significant terms.
Today, we move from the "why" to the "how." Our goal is to compute the Big-O time complexity of iterative code with loops and nested loops. This is a fundamental, mechanical skill you will use in every single coding interview to analyze your own solutions. By the end of this lesson, you'll be able to look at a block of code with for or while loops and confidently determine its time complexity.
The Building Blocks: From Simple Statements to Loops
Let's start with the basics. Any single, simple operation that doesn't depend on the size of the input is considered a constant time operation, or .
Examples of operations include:
- An assignment:
int x = 5; - An arithmetic operation:
x + y - Accessing an element in an array by its index:
myArray[3] - Pushing or popping from a stack.
Our task is to combine the complexities of these simple operations as they are organized within loops.
Rule 1: Analyzing Sequential Loops
What happens when you have two loops, one after the other? You simply add their complexities.
Consider this Java-like pseudocode:
// Assume 'n' is the size of array1 and 'm' is the size of array2
// Loop 1
for (int i = 0; i < n; i++) {
System.out.println(array1[i]); // O(1) operation
}
// Loop 2
for (int j = 0; j < m; j++) {
System.out.println(array2[j]); // O(1) operation
}
The first loop runs n times, so its complexity is . The second loop runs m times, so its complexity is . The total complexity is .
Important: If both loops ran n times, the complexity would be . Following the rule of dropping constants from our last lesson, this simplifies to just .
To see this principle in action with clear code examples, please watch the first part of this video.
Big O Notation - Code Examples
The following video from the 'Keep On Coding' channel demonstrates how to analyze code with two separate (sequential) for loops.
Watch from 01:28 to 03:34. The key idea here is that for sequential, non-nested blocks of code, we sum their time complexities.
Rule 2: Analyzing Nested Loops
This is the most common pattern you'll encounter. When loops are nested, you multiply their complexities.
A simple nested loop looks like this:
// Assume 'n' is the length of the array
for (int i = 0; i < n; i++) { // Outer loop runs n times
for (int j = 0; j < n; j++) { // Inner loop runs n times for EACH outer iteration
// O(1) operation
}
}
The inner loop performs operations. The outer loop executes the inner loop times. Therefore, the total number of operations is . The complexity is .

The following reading provides a clear, systematic breakdown of the rules for analyzing sequences and different types of loops. Think of it as your "rulebook" for this process.
This guide from the University of Wisconsin-Madison outlines the formal rules for determining complexity for different code structures.
Read the section titled 'How to Determine Complexities'. Focus on the rules for 'Sequence of statements', 'for loops', and both types of 'Nested loops' (independent and dependent). This will give you a solid framework for the next examples.
Common Variations of Nested Loops
While the simple case is common, you'll often see two important variations in interviews.
1. Different Loop Bounds: O(N * M)
If the nested loops iterate over different variables, the complexity is the product of those variables.
for (int i = 0; i < n; i++) { // Runs n times
for (int j = 0; j < m; j++) { // Runs m times
// O(1) operation
}
}
The complexity here is . Don't just default to . Always check the loop bounds.
2. Dependent Inner Loop: Still O(N²)
This pattern is very common in problems involving pairs of elements from an array.
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
// Find all pairs (i, j)
}
}
At first glance, this might seem more complex. Let's break it down:
- When
i = 0, the inner loop runsntimes. - When
i = 1, the inner loop runsn-1times. - When
i = 2, the inner loop runsn-2times. - ...
- When
i = n-1, the inner loop runs1time.
The total number of operations is the sum of an arithmetic series: . This sum is equal to .
Applying our Big-O simplification rules:
- We expand it to .
- We drop the lower-order term (), leaving .
- We drop the constant (), leaving .
So, the final complexity is .
The next video provides an excellent visual intuition for why this triangular pattern still results in complexity, and also covers the case.
Big-O Notation - For Coding Interviews
This video from NeetCode, a top resource for interview prep, clearly explains the complexity of nested loops, including the triangular pattern.
Watch from 06:37 to 10:49. Pay close attention to the visual explanation of why the sum 1 + 2 + ... + N is O(N²). Also, note the distinction made for O(N*M) and O(N³).
Practice: Let's Analyze Some Code
Now, let's put this into practice. The best way to get comfortable with complexity analysis is to work through examples. The following video presents several short code snippets. For each one, I encourage you to:
- Pause the video when the code appears.
- Try to determine the time complexity yourself using the rules we've discussed.
- Then, watch the explanation to check your understanding.
This exercise is particularly valuable because it includes a common "trick" question that interviewers sometimes use to see if you are really paying attention to the code.
Big O Notation - Code Examples
This video from 'Keep On Coding' will serve as a practical exercise. It walks through several examples, including nested loops, loops with different bounds, and a tricky case with a constant-time inner loop.
Watch from 03:24 to 06:40. Actively participate by pausing and solving each problem yourself before viewing the solution.
Summary of Key Takeaways
You've now learned the core mechanics of analyzing iterative code. Remember these rules:
- Rule of Summation: For sequential blocks of code, add their complexities. The largest term will dominate. (e.g., ).
- Rule of Multiplication: For nested loops, multiply their complexities. (e.g., An loop containing an loop is ).
- Count the Innermost Operations: Ultimately, you are counting how many times the most deeply nested line of code will run as a function of the input size(s).
- Read the Code Carefully: Don't just count the number of
forloops. Always check the loop termination conditions. A loop might run a constant number of times, or its bounds might depend on an outer loop's variable.
In this lesson, we focused on complexities like and . However, many highly efficient algorithms rely on different growth rates. In our next lesson, we will formally compare these common complexity classes and introduce logarithmic time, , which is key to understanding efficient searching and sorting algorithms.