Question is simple, I want to map every number from 0 to N-1 to a number of elements K < N such that:
1,2,3,…,i-1 maps to element 1
i, i+1, i+2,…,i+k-1 maps to element 2
… and so on until
i+k+…+z, i+k+…+z+1, i+k+…+z+2, …, N-1 maps to element K
Note: i,j, k,…,z are different values (otherwise I wouldn’t have used different letters 🙂 ).
Is there a way to have a structure and a function f(i) returning the corresponding element in time O(1) occupying a reasonable amount of space? (A vector of N elements with each element from the range pointing to the element it affects is NOT a reasonable amount of space)
I can think of B trees which would get me a O(log(n)) access time, but I’m curious if there’s a O(1) efficient solution.
Thanks in advance!
Bruno
If your i,k,…,z are arbitrary, then no algorithm with a time constraint of O(1) and a reasonable space constraint of < O(N) comes to mind. If there is some regularity in your bounds, then of course you can put that into use: e.g. if each range contains an even number of elements, then a simple solution be to have a lookup table that is acccessed using [i_N/2]. In the general case, you would need to have a matching folding-function for your number 0…N – one that satisfies the constraint k-mapping(i) != k-mapping(i+1) => folding-function(i) != folding-function(i+1).
If only some elements in your map are accessed frequently, you could also build a cache for the mapping, leading to O(1) in the cache-hit case and O(lookup-function) for the cache-miss. Of course, the cache lookup would impact the time spent for each element, even in case of a cache-miss, but it would not affect the O-complexity of your algorithm.
Edit
Basically what you want to implement can be expressed as a Pascal case statement with sets as labels:
For this problem, a Google search indeed turns out an interesting paper:
Alas, you don’t have a sparse case set, but as far as I can see, the algorithm should require only minimal adaption for dense case sets that have lots of consecutive results.
For the general problem of creating efficient code for case statements, Zhao and Amarla have an interesting paper that uses profiling to achieve something similar to using a cache. Their paper is also interesting for the related work section, which refers to a paper from Kannan and Proebsting (Correction to producing good code for the case statement.) which requires an O(n^2) setup time for clustering. However, I have not access to this paper, and it sounds like that this would only produce an extremely optimized search tree, therefore leading to a runtime of O(log(n)).