What is the runtime for this recursive flatten function? My guess is that it's linear; can someone explain why?
const arr = [
[14, [45, 60], 6, [47, [1, 2, [14, [45, 60], 6, [47, [1, 2]], 9]]], 9],
];
function flatten(items) {
const flat = [];
items.forEach(item => {
if (Array.isArray(item)) {
flat.push(...flatten(item));
} else {
flat.push(item);
}
});
return flat;
}
As pointed out in the comments, since each element is indeed touched only once, the time complexity is intuitively
O(N)
.A non-trivial1 example of such a case would be when the array is organized similarly to a full binary tree:
[[[a, b], [c, d]], [[e, f], [g, h]]], [[[i, j], [k, l]], [[m, n], [o, p]]]
The time complexity recurrence relation is:
Where
2 * T(n / 2)
comes from recursive calls toflatten
the sub-trees, andO(n)
frompush
ing2 the results, which are two arrays of lengthn / 2
.1) non-trivial means that no element is wrapped unnecessarily, e.g.
[[[a]]]
.2) This implicitly assumes that
k
push operations areO(k)
amortized, which is not guaranteed by the standard, but is still true for most implementations.A "true"
O(N)
solution will directly append to the final output array instead of creating intermediate arrays:The recurrence becomes
T(n) = 2 * T(n / 2) + O(1)
for the previous example, which is linear.Again this assumes both 1) and 2).