percolate
is a recursive function whose implicit input is the global array arr
of size n
. The function may call itself recursively O(lg n) times, with each invocation doing O(1) work, leading to your O(lg n) running time. However, each call allocates a constant amount of temporary storage.
If the implementation language allocates this memory on a stack and reuses stack frames via tail-recursion optimization, then the total memory usage of the algorithm is indeed O(1).
However, if there is no tail-recursion optimization, the memory allocated for each call remains in use and not reclaimed until that particular call returns, which will not be until after all the recursive calls below it return. For a call tree with O(lg n) height, that means O(lg n) memory used by the function.
All this goes to show that an algorithm which uses O(1) memory in theory can be implemented inefficiently to use O(lg n) memory in practice.