Is this correct?
No.
When you remove an element from the table, the table.size
decreases, and current % table.size
expression generally ends up pointing at another irrelevant element.
For example, 44 % 11
is 0
but 44 % 10
is 4
, an element in a totally different place.
Is it n*logn?
No.
If table
is just a random-access array, it can take n
operations to remove an element.
For example, if m = 1
, the program, after fixing the point above, would always remove the first element of the array.
When an array implementation is naive enough, it takes table.size
operations to relocate the array each time, leading to a total to about n^2 / 2
operations in total.
Now, it would be n log n
if table
was backed up, for example, by a balanced binary search tree with implicit indexes instead of keys, as well as split and merge primitives. That's a treap for example, here is what results from a quick search for an English source.
Such a data structure could be used as an array with O(log n)
costs for access, merge and split.
But nothing so far suggests this is the case, and there is no such data structure in most languages' standard libraries.
Can you do it better?
Correction: partially, yes; fully, maybe.
If we solve the problem backwards, we have the following sub-problem.
Let there be a circle of k
kids, and the pointer is currently at kid t
.
We know that, just a moment ago, there was a circle of k + 1
kids, but we don't know where, at which kid x
, the pointer was.
Then we counted to m
, removed the kid, and the pointer ended up at t
.
Whom did we just remove, and what is x
?
Turns out the "what is x
" part can be solved in O(1)
(drawing can be helpful here), so the finding the last kid standing is doable in O(n)
.
As pointed out in the comments, the whole thing is called Josephus Problem, and its variants are studied extensively, e.g., in Concrete Mathematics by Knuth et al.
However, in O(1)
per step, this only finds the number of the last standing kid.
It does not automatically give the whole order of counting the kids out.
There certainly are ways to make it O(log(n))
per step, O(n log(n))
in total.
But as for O(1)
, I don't know at the moment.