It may be helpful to think of a general number interval, say 1 to 100.
- If you loop through that interval one by one, the loop will be O(n)
- If you loop through it by any linear step size, like 2 at a time or 10 at a time, the loop will be O(n/2), O(n/10), etc., which still simplifies to O(n).
However, if the size of the loop step changes each time through the loop, you get different results:
- If you loop through the range while doubling the step each time (1, 2, 4, 8, 16, 32, 64), you will end up running the loop only 7 times before reaching the end. This is exponential growth of the step size, which corresponds to a logarithmic number of times through the loop: 1 + log(100) with log base 2 (rounded down), which simplifies to O(log n).
- If you multiply your step size by 3 each time (1, 3, 9, 27, 81), it will loop 1 + log(100) times with log base 3, which still simplifies to O(log n). And so on.
So in your example, you have your outer loop O(n) times your inner loop O(log n), leading to a combined O(n * log n).
Great examples of different time complexities can be found in this answer.