ONM time complexity
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
O(N + M) time complexity appears when an algorithm processes two independent inputs and touches each of them linearly. It is an important distinction because it describes work that scales with both sizes separately, instead of multiplying them together as O(N * M) would.
What O(N + M) Actually Means
When you see O(N + M), read it as "one pass over data of size N, plus one pass over data of size M." The algorithm is still linear, but linear in two dimensions.
This is common when:
- You merge or compare two collections.
- You traverse a graph represented as vertices plus edges.
- You preprocess one structure and then scan another.
The key idea is independence. If the amount of work done for one input does not repeat for every item in the other input, the complexity is usually additive rather than multiplicative.
Example: Merge Two Sorted Arrays
Merging two sorted arrays is a classic O(N + M) algorithm. You keep one pointer in each list, compare the current values, and append the smaller one to the result. Each element is consumed once.
Why is this O(N + M)?
- Each element in
leftis examined at most once. - Each element in
rightis examined at most once. - The cleanup step appends only the remaining unseen items.
There is no nested full scan, so the lists are not multiplying each other's cost.
Example: Graph Traversal
Depth-first search and breadth-first search on an adjacency-list graph are often described as O(V + E), which is the same pattern. V is the number of vertices and E is the number of edges.
The traversal visits every vertex once and inspects every edge once. That is why the complexity is additive. Even though there is a loop inside another loop, the total work across the whole run still sums to V + E, not V * E.
How To Tell Additive And Multiplicative Costs Apart
A good mental model is to ask one question: does the algorithm restart a full pass of one input for every element of the other input?
If yes, the cost tends to be multiplicative.
That function is O(N * M) in the worst case because every element of a may be compared with every element of b.
By contrast, a hash-based version is additive:
This version is O(N + M) because building the set is one linear pass, then scanning the second list is another linear pass.
When O(N + M) Can Be Simplified
In asymptotic analysis, if N and M always grow together at roughly the same rate, some authors simplify O(N + M) to O(N). That is mathematically fine in a narrow context, but it hides useful information when the inputs represent different resources.
For example, if one array has ten items and the other has ten million, O(N + M) communicates the dominant cost much more honestly than a single O(N) symbol. In practice, keeping both variables visible usually makes the analysis clearer.
Common Pitfalls
The most common mistake is assuming that any nested loop must be O(N * M). That is not always true. Graph traversal is the standard counterexample because the inner iterations are spread across the edges collectively, not repeated from scratch for every vertex.
Another mistake is dropping one variable too early. If the algorithm truly depends on two independent sizes, writing only O(N) loses detail that matters for performance discussions and API design.
People also confuse O(N + M) with "slower than linear." It is still linear with respect to total input size. The plus sign does not make it a different class from practical linear-time behavior.
Finally, be careful with preprocessing. An algorithm may start as O(N + M) in theory, then become O(N log N + M) if you sort one input first. State each stage explicitly.
Summary
- '
O(N + M)means linear work over two independent inputs.' - Merging sorted lists and traversing graphs are standard examples.
- Additive cost appears when each input is processed once, not repeatedly against the other.
- Nested loops do not automatically imply
O(N * M). - Keeping both variables visible often explains performance better than collapsing everything into one symbol.
Related reading
- OpenMp C algorithms for min, max, median, average
- Operation on every pair of element in a list
- Optimal algorithm for returning top k values from an array of length N
- Optimal Algorithm for Winning Hangman
- onnxruntime inference is way slower than pytorch on GPU
- OpenCV Sum of squared differences speed
- optimal algorithm grouping data in javascript
- Optimal algorithm to calculate the result of a continued fraction

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.