I'm Telecommunication student so I don't have Computer Science background, just in case if my question looks stupid.
Here is my scenario:
Consider an empty array named
ARR
with sizeN
, we also have an array namedMAP
with sizeN
that stores the state ofARR
cells,ON
for filled,OFF
for empty, initiallyARR
is empty so every corresponding cell inMAP
is set toOFF
.we keep the next empty cell index in a variable named
NEXT
, initially sinceARR
is empty,NEXT
is set to 0.NEXT
always point to the first indexi
in the arrayMAP
such thatMAP[i]
isOFF
, if any exists.a function named
add(element)
always adds element intoARR
at indexNEXT
, sets corresponding cell inMAP
toON
.a function named
insert(element, index)
adds element intoARR
at index specified by user, sets corresponding cell inMAP
toON
.a function named
delete(index)
removes element fromARR
at index specified by user, sets corresponding cell inMAP
toOFF
.
My question:
How to update NEXT
variable so it points to next empty cell index in ARR
.
I know I can run a search on MAP
from 0 to N and stop at the first occurrence of OFF
and store its index as NEXT
, but from what I read from online sources it has O(N) performance which is not great, I want to know if there are any better algorithms for this job or not, if not, can I design one myself? which books/online doc should I look into?
Thanks.
1 Answer 1
I'm assuming that you're on a RAM machine with word size $\Theta(\log N$). Keep a van Emde Boas tree $T$ storing the empty positions (integers from 1ドル$ to $N$).
Whenever you insert an element $i$, delete $i$ from $T$ (in $O(\log \log N$) time) and set NEXT
to the minimum element in $T$ (in $O(1)$ time).
Whenever you delete an element $i$, insert $i$ to $T$ and set NEXT
to the minimum between the current values of NEXT
and $i$.
This requires $O(\log \log N)$ time per operation but would require time $O(N \log \log N)$ to build the tree.
To improve the construction time to $O(N)$ you can start with a tree containing only the index 1ドル$. Then during the first $N-1$ operations do the following: before the $i$-th operation is performed check if MAP[i+1]=OFF
. If this is the case, then add $i+1$ to $T$. Proceed with the operation normally. This is taking advantage of the fact that, after the $i$-th operation is performed, we must necessarily have NEXT<=i+1
.
You can't get much better solutions since you essentially need to solve the predecessor problem which admits a lower bound of $\Omega( \frac{\log \log N}{\log \log \log N})$ for a word size of $\Theta(\log N)$.
For a slower but easier to implement solution replace the van Emde Boas tree with an AVL tree. The initial tree can be built in $O(N)$ time (the keys are sorted) and each operation requires $O(\log N)$ time.
-
$\begingroup$ Thanks for the solution, I'll try to implement it into code, I just have a question, $O(N \log \log N)$ to build the tree is juts a 1 time operation right? or per every
add
,insert
,delete
I should construct the tree? $\endgroup$Mahdi Baghbani– Mahdi Baghbani2021年07月16日 11:13:54 +00:00Commented Jul 16, 2021 at 11:13 -
$\begingroup$ The tree is constructed only once, at the same time when
ARR
andMAP
are created and initialized. $\endgroup$Steven– Steven2021年07月16日 11:24:49 +00:00Commented Jul 16, 2021 at 11:24
NEXT
always point to the first index $i$ in the arrayMAP
such thatMAP[i]
isOFF
, if any? $\endgroup$