On On On?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The expression O(n) + O(n) = O(n) looks suspicious the first time you see it, because ordinary arithmetic says n + n = 2n. In asymptotic analysis, though, Big O notation does not track exact constants. It tracks how fast the running time grows as the input becomes large.
What Big O Is Actually Describing
Big O gives an upper bound on growth rate. When two algorithms both scale linearly with the input size, they both belong to the same class even if one takes twice as much work per element.
That is why these two loops have the same asymptotic complexity:
Each loop visits every element once, so each is O(n). If you run them one after the other, the total work is still linear.
Why O(n) + O(n) Collapses to O(n)
Suppose an algorithm performs two consecutive passes over the same input:
The first loop is O(n). The second loop is also O(n). So the exact running-time shape is closer to c1 * n + c2 * n, or (c1 + c2) * n. That is still linear growth, so the Big O class is O(n).
This is the same reason we simplify:
- '
O(3n)toO(n)' - '
O(1000n)toO(n)' - '
O(n + 5)toO(n)'
The constants matter in real performance, but they do not change the asymptotic category.
Exact Cost vs Asymptotic Cost
It is important not to confuse "same Big O" with "same speed." Two O(n) algorithms can behave very differently in practice.
For example:
Both are O(n), but ten_passes does about ten times as much work. Big O intentionally hides that constant factor because it is meant to compare long-run growth, not exact instruction counts.
If you care about concrete runtime, you still need benchmarking or more precise cost analysis.
When Addition Does Change the Result
The simplification only works when one term does not outgrow the other. If the costs have different growth rates, the dominant term wins.
Examples:
- '
O(n) + O(n^2) = O(n^2)' - '
O(log n) + O(n) = O(n)' - '
O(n) + O(n log n) = O(n log n)'
A simple example:
The nested loop is O(n^2), and the final pass is O(n). The total is O(n^2 + n), which simplifies to O(n^2) because the quadratic term dominates for large n.
Sequential vs Nested Work
Another source of confusion is mixing sequential loops with nested loops. Two loops one after the other usually add:
That is O(n) + O(n), which becomes O(n).
A loop inside another loop multiplies:
That is O(n * n), which is O(n^2).
This distinction matters more than the algebra itself. Many mistakes in complexity analysis happen because sequential work is accidentally treated like nested work, or the other way around.
A More Formal View
If f(n) and g(n) are both bounded above by a constant multiple of n, then their sum is also bounded above by a constant multiple of n.
In other words, if:
- '
f(n) <= c1 * n' - '
g(n) <= c2 * n'
then:
- '
f(n) + g(n) <= (c1 + c2) * n'
That is exactly the definition needed to say the sum is still O(n).
Common Pitfalls
The main mistake is treating Big O like exact arithmetic instead of a growth-rate classification. Another is concluding that two O(n) algorithms are equally fast in practice, even though constant factors can matter a lot. Developers also often confuse consecutive loops with nested loops and accidentally turn addition into multiplication. A final problem is simplifying too early and losing the information that one linear algorithm makes two passes while another makes only one, which can still matter for real-world performance.
Summary
- '
O(n) + O(n)simplifies toO(n)because Big O ignores constant factors.' - Two linear passes still grow linearly with input size.
- Same Big O does not mean same actual runtime.
- Different growth rates do not collapse the same way; the dominant term wins.
- Analyze whether work is sequential or nested before simplifying the expression.

